From noreply at buildbot.pypy.org Mon Sep 2 18:08:40 2013 From: noreply at buildbot.pypy.org (Manuel Jacob) Date: Mon, 2 Sep 2013 18:08:40 +0200 (CEST) Subject: [pypy-commit] pypy refactor-translator: Remove import. Message-ID: <20130902160840.1B94D1C0205@cobra.cs.uni-duesseldorf.de> Author: Manuel Jacob Branch: refactor-translator Changeset: r66764:472f2b6aee19 Date: 2013-09-02 13:06 +0100 http://bitbucket.org/pypy/pypy/changeset/472f2b6aee19/ Log: Remove import. diff --git a/rpython/translator/driver.py b/rpython/translator/driver.py --- a/rpython/translator/driver.py +++ b/rpython/translator/driver.py @@ -10,7 +10,6 @@ from rpython.tool.udir import udir from rpython.rlib.debug import debug_start, debug_print, debug_stop from rpython.rlib.entrypoint import secondary_entrypoints -from rpython.rtyper.typesystem import getfunctionptr import py from rpython.tool.ansi_print import ansi_log From noreply at buildbot.pypy.org Mon Sep 2 19:00:47 2013 From: noreply at buildbot.pypy.org (Manuel Jacob) Date: Mon, 2 Sep 2013 19:00:47 +0200 (CEST) Subject: [pypy-commit] pypy refactor-translator: Remove ootype-specific code from translate.py. Message-ID: <20130902170047.3C03A1C36C7@cobra.cs.uni-duesseldorf.de> Author: Manuel Jacob Branch: refactor-translator Changeset: r66766:f006a45518f2 Date: 2013-09-02 15:43 +0100 http://bitbucket.org/pypy/pypy/changeset/f006a45518f2/ Log: Remove ootype-specific code from translate.py. diff --git a/rpython/translator/goal/translate.py b/rpython/translator/goal/translate.py --- a/rpython/translator/goal/translate.py +++ b/rpython/translator/goal/translate.py @@ -236,11 +236,6 @@ if args is None: args = [] drv = driver.TranslationDriver(config=config) - # patch some attributes of the os module to make sure they - # have the same value on every platform. - if config.translation.backend in ('cli', 'jvm'): - from rpython.translator.oosupport.support import patch_os - drv.old_cli_defs = patch_os() target = targetspec_dic['target'] spec = target(drv, args) From noreply at buildbot.pypy.org Mon Sep 2 19:00:45 2013 From: noreply at buildbot.pypy.org (Manuel Jacob) Date: Mon, 2 Sep 2013 19:00:45 +0200 (CEST) Subject: [pypy-commit] pypy refactor-translator: Remove dead build_main_for_shared() from genc.py. Message-ID: <20130902170045.E7F5E1C36C6@cobra.cs.uni-duesseldorf.de> Author: Manuel Jacob Branch: refactor-translator Changeset: r66765:a05ed146e9aa Date: 2013-09-02 15:43 +0100 http://bitbucket.org/pypy/pypy/changeset/a05ed146e9aa/ Log: Remove dead build_main_for_shared() from genc.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 @@ -323,34 +323,6 @@ return res.out, res.err return res.out - def build_main_for_shared(self, shared_library_name, entrypoint, exe_name): - import time - time.sleep(1) - self.shared_library_name = shared_library_name - # build main program - eci = self.get_eci() - kw = {} - if self.translator.platform.cc == 'gcc': - kw['libraries'] = [self.shared_library_name.purebasename[3:]] - kw['library_dirs'] = [self.targetdir] - else: - kw['libraries'] = [self.shared_library_name.new(ext='')] - eci = eci.merge(ExternalCompilationInfo( - separate_module_sources=[''' - int %s(int argc, char* argv[]); - - int main(int argc, char* argv[]) - { return %s(argc, argv); } - ''' % (entrypoint, entrypoint) - ], - **kw - )) - eci = eci.convert_sources_to_files( - cache_dir=self.targetdir) - return self.translator.platform.compile( - [], eci, - outputfilename=exe_name) - def compile(self, exe_name=None): assert self.c_source_filename assert not self._compiled From noreply at buildbot.pypy.org Mon Sep 2 21:36:48 2013 From: noreply at buildbot.pypy.org (rlamy) Date: Mon, 2 Sep 2013 21:36:48 +0200 (CEST) Subject: [pypy-commit] pypy less-stringly-ops: Move implementation of FlowObjSpace.iter() to op.iter Message-ID: <20130902193648.CB08E1C0962@cobra.cs.uni-duesseldorf.de> Author: Ronan Lamy Branch: less-stringly-ops Changeset: r66767:67c3af63e05a Date: 2013-08-31 18:00 +0100 http://bitbucket.org/pypy/pypy/changeset/67c3af63e05a/ Log: Move implementation of FlowObjSpace.iter() to op.iter diff --git a/rpython/flowspace/objspace.py b/rpython/flowspace/objspace.py --- a/rpython/flowspace/objspace.py +++ b/rpython/flowspace/objspace.py @@ -207,14 +207,6 @@ def not_(self, w_obj): return const(not self.frame.guessbool(self.bool(w_obj))) - def iter(self, w_iterable): - if isinstance(w_iterable, Constant): - iterable = w_iterable.value - if isinstance(iterable, unrolling_iterable): - return const(iterable.get_unroller()) - w_iter = self.frame.do_operation("iter", w_iterable) - return w_iter - def next(self, w_iter): frame = self.frame if isinstance(w_iter, Constant): diff --git a/rpython/flowspace/operation.py b/rpython/flowspace/operation.py --- a/rpython/flowspace/operation.py +++ b/rpython/flowspace/operation.py @@ -6,6 +6,7 @@ import __builtin__ import __future__ import operator +from rpython.rlib.unroll import unrolling_iterable, _unroller from rpython.tool.sourcetools import compile2 from rpython.flowspace.model import (Constant, WrapException, const, Variable, SpaceOperation) @@ -276,7 +277,6 @@ add_operator('cmp', 2, 'cmp', pyfunc=cmp, pure=True) # rich cmps preferred add_operator('coerce', 2, 'coerce', pyfunc=coerce, pure=True) add_operator('contains', 2, 'contains', pure=True) -add_operator('iter', 1, 'iter', pyfunc=iter) add_operator('next', 1, 'next', pyfunc=next) #add_operator('call', 3, 'call') add_operator('get', 3, 'get', pyfunc=get, pure=True) @@ -285,9 +285,25 @@ add_operator('userdel', 1, 'del', pyfunc=userdel) add_operator('buffer', 1, 'buffer', pyfunc=buffer, pure=True) # see buffer.py +class Iter(HLOperation): + opname = 'iter' + arity = 1 + can_overflow = False + canraise = [] + pyfunc = staticmethod(iter) + + def constfold(self): + w_iterable, = self.args + if isinstance(w_iterable, Constant): + iterable = w_iterable.value + if isinstance(iterable, unrolling_iterable): + return const(iterable.get_unroller()) +op.iter = Iter + # Other functions that get directly translated to SpaceOperators func2op[type] = op.type func2op[operator.truth] = op.bool +func2op[__builtin__.iter] = op.iter if hasattr(__builtin__, 'next'): func2op[__builtin__.next] = op.next From noreply at buildbot.pypy.org Mon Sep 2 21:36:50 2013 From: noreply at buildbot.pypy.org (rlamy) Date: Mon, 2 Sep 2013 21:36:50 +0200 (CEST) Subject: [pypy-commit] pypy less-stringly-ops: kill FSException Message-ID: <20130902193650.2358C1C1354@cobra.cs.uni-duesseldorf.de> Author: Ronan Lamy Branch: less-stringly-ops Changeset: r66768:e059c6654247 Date: 2013-08-31 18:07 +0100 http://bitbucket.org/pypy/pypy/changeset/e059c6654247/ Log: kill FSException diff --git a/rpython/flowspace/flowcontext.py b/rpython/flowspace/flowcontext.py --- a/rpython/flowspace/flowcontext.py +++ b/rpython/flowspace/flowcontext.py @@ -40,9 +40,6 @@ self.w_type = w_type self.w_value = w_value - def get_w_value(self, _): - return self.w_value - def __str__(self): return '[%s: %s]' % (self.w_type, self.w_value) @@ -1286,7 +1283,7 @@ # instead of the traceback, we store the unroller object, # wrapped. frame.pushvalue(unroller) - frame.pushvalue(operationerr.get_w_value(frame.space)) + frame.pushvalue(operationerr.w_value) frame.pushvalue(operationerr.w_type) frame.last_exception = operationerr return self.handlerposition # jump to the handler From noreply at buildbot.pypy.org Mon Sep 2 21:36:51 2013 From: noreply at buildbot.pypy.org (rlamy) Date: Mon, 2 Sep 2013 21:36:51 +0200 (CEST) Subject: [pypy-commit] pypy less-stringly-ops: Move FSException to flowspace.model Message-ID: <20130902193651.717001C0962@cobra.cs.uni-duesseldorf.de> Author: Ronan Lamy Branch: less-stringly-ops Changeset: r66769:6209a2e9528e Date: 2013-09-01 10:48 +0100 http://bitbucket.org/pypy/pypy/changeset/6209a2e9528e/ Log: Move FSException to flowspace.model diff --git a/rpython/flowspace/flowcontext.py b/rpython/flowspace/flowcontext.py --- a/rpython/flowspace/flowcontext.py +++ b/rpython/flowspace/flowcontext.py @@ -9,7 +9,7 @@ from rpython.tool.stdlib_opcode import host_bytecode_spec from rpython.flowspace.argument import CallSpec from rpython.flowspace.model import (Constant, Variable, Block, Link, - c_last_exception, SpaceOperation, const) + c_last_exception, SpaceOperation, const, FSException) from rpython.flowspace.framestate import (FrameState, recursively_unflatten, recursively_flatten) from rpython.flowspace.specialcase import (rpython_print_item, @@ -34,15 +34,6 @@ def __init__(self, value): self.value = value -class FSException(Exception): - def __init__(self, w_type, w_value): - assert w_type is not None - self.w_type = w_type - self.w_value = w_value - - def __str__(self): - return '[%s: %s]' % (self.w_type, self.w_value) - class ImplicitOperationError(FSException): pass @@ -655,7 +646,7 @@ self.last_exception = operr raise operr else: - raise space.exc_wrap(TypeError( + raise const(TypeError( "raise: no active exception to re-raise")) w_value = space.w_None diff --git a/rpython/flowspace/model.py b/rpython/flowspace/model.py --- a/rpython/flowspace/model.py +++ b/rpython/flowspace/model.py @@ -346,6 +346,16 @@ return False +class FSException(Exception): + def __init__(self, w_type, w_value): + assert w_type is not None + self.w_type = w_type + self.w_value = w_value + + def __str__(self): + return '[%s: %s]' % (self.w_type, self.w_value) + + class UnwrapException(Exception): """Attempted to unwrap a Variable.""" @@ -367,6 +377,8 @@ # to appear in a flow graph if type(obj) is type_with_bad_introspection: raise WrapException + elif isinstance(obj, Exception): + return FSException(Constant(type(obj)), Constant(obj)) return Constant(obj) class SpaceOperation(object): diff --git a/rpython/flowspace/objspace.py b/rpython/flowspace/objspace.py --- a/rpython/flowspace/objspace.py +++ b/rpython/flowspace/objspace.py @@ -9,11 +9,11 @@ from rpython.flowspace.argument import CallSpec from rpython.flowspace.model import (Constant, Variable, WrapException, - UnwrapException, checkgraph, const) + UnwrapException, checkgraph, const, FSException) from rpython.flowspace.bytecode import HostCode from rpython.flowspace.operation import op from rpython.flowspace.flowcontext import (FlowSpaceFrame, fixeggblocks, - FSException, FlowingError) + FlowingError) from rpython.flowspace.generator import (tweak_generator_graph, bootstrap_generator) from rpython.flowspace.pygraph import PyGraph @@ -124,11 +124,6 @@ fn = types.FunctionType(code, globals, code.co_name, defaults) return Constant(fn) - def exc_wrap(self, exc): - w_value = const(exc) - w_type = const(type(exc)) - return FSException(w_type, w_value) - def exception_match(self, w_exc_type, w_check_class): """Checks if the given exception type matches 'w_check_class'.""" frame = self.frame @@ -175,7 +170,7 @@ else: # the only case left here is (inst, None), from a 'raise inst'. if not frame.guessbool(self.is_(w_arg2, self.w_None)): - raise self.exc_wrap(TypeError( + raise const(TypeError( "instance exception may not have a separate value")) w_value = w_arg1 w_type = self.type(w_value) @@ -215,7 +210,7 @@ try: v, next_unroller = it.step() except IndexError: - raise self.exc_wrap(StopIteration()) + raise const(StopIteration()) else: frame.replace_in_stack(it, next_unroller) return const(v) @@ -250,7 +245,7 @@ try: mod = __import__(name, glob, loc, frm, level) except ImportError as e: - raise self.exc_wrap(e) + raise const(e) return const(mod) def import_from(self, w_module, w_name): @@ -264,8 +259,7 @@ try: return const(getattr(w_module.value, w_name.value)) except AttributeError: - raise self.exc_wrap(ImportError( - "cannot import name '%s'" % w_name.value)) + raise const(ImportError("cannot import name '%s'" % w_name.value)) def call_method(self, w_obj, methname, *arg_w): w_meth = self.getattr(w_obj, const(methname)) From noreply at buildbot.pypy.org Mon Sep 2 21:36:52 2013 From: noreply at buildbot.pypy.org (rlamy) Date: Mon, 2 Sep 2013 21:36:52 +0200 (CEST) Subject: [pypy-commit] pypy less-stringly-ops: Move implementation of FlowObjSpace.next() to op.next Message-ID: <20130902193652.A6E551C0962@cobra.cs.uni-duesseldorf.de> Author: Ronan Lamy Branch: less-stringly-ops Changeset: r66770:d0d7f7735df4 Date: 2013-09-01 11:37 +0100 http://bitbucket.org/pypy/pypy/changeset/d0d7f7735df4/ Log: Move implementation of FlowObjSpace.next() to op.next diff --git a/rpython/flowspace/objspace.py b/rpython/flowspace/objspace.py --- a/rpython/flowspace/objspace.py +++ b/rpython/flowspace/objspace.py @@ -18,7 +18,6 @@ bootstrap_generator) from rpython.flowspace.pygraph import PyGraph from rpython.flowspace.specialcase import SPECIAL_CASES -from rpython.rlib.unroll import unrolling_iterable, _unroller from rpython.rlib import rstackovf @@ -202,22 +201,6 @@ def not_(self, w_obj): return const(not self.frame.guessbool(self.bool(w_obj))) - def next(self, w_iter): - frame = self.frame - if isinstance(w_iter, Constant): - it = w_iter.value - if isinstance(it, _unroller): - try: - v, next_unroller = it.step() - except IndexError: - raise const(StopIteration()) - else: - frame.replace_in_stack(it, next_unroller) - return const(v) - w_item = frame.do_operation("next", w_iter) - frame.guessexception([StopIteration, RuntimeError], force=True) - return w_item - def getattr(self, w_obj, w_name): # handling special things like sys diff --git a/rpython/flowspace/operation.py b/rpython/flowspace/operation.py --- a/rpython/flowspace/operation.py +++ b/rpython/flowspace/operation.py @@ -277,7 +277,6 @@ add_operator('cmp', 2, 'cmp', pyfunc=cmp, pure=True) # rich cmps preferred add_operator('coerce', 2, 'coerce', pyfunc=coerce, pure=True) add_operator('contains', 2, 'contains', pure=True) -add_operator('next', 1, 'next', pyfunc=next) #add_operator('call', 3, 'call') add_operator('get', 3, 'get', pyfunc=get, pure=True) add_operator('set', 3, 'set', pyfunc=set) @@ -300,6 +299,31 @@ return const(iterable.get_unroller()) op.iter = Iter +class Next(HLOperation): + opname = 'next' + arity = 1 + can_overflow = False + canraise = [] + pyfunc = staticmethod(next) + + def eval(self, frame): + w_iter, = self.args + if isinstance(w_iter, Constant): + it = w_iter.value + if isinstance(it, _unroller): + try: + v, next_unroller = it.step() + except IndexError: + raise const(StopIteration()) + else: + frame.replace_in_stack(it, next_unroller) + return const(v) + w_item = frame.do_op(self) + frame.guessexception([StopIteration, RuntimeError], force=True) + return w_item +op.next = Next + + # Other functions that get directly translated to SpaceOperators func2op[type] = op.type func2op[operator.truth] = op.bool From noreply at buildbot.pypy.org Mon Sep 2 21:36:53 2013 From: noreply at buildbot.pypy.org (rlamy) Date: Mon, 2 Sep 2013 21:36:53 +0200 (CEST) Subject: [pypy-commit] pypy less-stringly-ops: Move implementation of FlowObjSpace.getattr() to op.getatttr Message-ID: <20130902193653.D73081C0962@cobra.cs.uni-duesseldorf.de> Author: Ronan Lamy Branch: less-stringly-ops Changeset: r66771:3a5b76cb6051 Date: 2013-09-01 13:50 +0100 http://bitbucket.org/pypy/pypy/changeset/3a5b76cb6051/ Log: Move implementation of FlowObjSpace.getattr() to op.getatttr diff --git a/rpython/flowspace/objspace.py b/rpython/flowspace/objspace.py --- a/rpython/flowspace/objspace.py +++ b/rpython/flowspace/objspace.py @@ -11,7 +11,7 @@ from rpython.flowspace.model import (Constant, Variable, WrapException, UnwrapException, checkgraph, const, FSException) from rpython.flowspace.bytecode import HostCode -from rpython.flowspace.operation import op +from rpython.flowspace.operation import op, NOT_REALLY_CONST from rpython.flowspace.flowcontext import (FlowSpaceFrame, fixeggblocks, FlowingError) from rpython.flowspace.generator import (tweak_generator_graph, @@ -21,22 +21,6 @@ from rpython.rlib import rstackovf -# the following gives us easy access to declare more for applications: -NOT_REALLY_CONST = { - Constant(sys): { - Constant('maxint'): True, - Constant('maxunicode'): True, - Constant('api_version'): True, - Constant('exit'): True, - Constant('exc_info'): True, - Constant('getrefcount'): True, - Constant('getdefaultencoding'): True, - # this is an incomplete list of true constants. - # if we add much more, a dedicated class - # might be considered for special objects. - } - } - # built-ins that can always raise exceptions builtins_exceptions = { int: [ValueError], @@ -80,10 +64,7 @@ # during flow graph construction w_NameError = 'NameError' w_UnboundLocalError = 'UnboundLocalError' - specialcases = SPECIAL_CASES - # objects which should keep their SomeObjectness - not_really_const = NOT_REALLY_CONST def build_flow(self, func): return build_flow(func, self) @@ -202,28 +183,6 @@ return const(not self.frame.guessbool(self.bool(w_obj))) - def getattr(self, w_obj, w_name): - # handling special things like sys - # unfortunately this will never vanish with a unique import logic :-( - if w_obj in self.not_really_const: - const_w = self.not_really_const[w_obj] - if w_name not in const_w: - return self.frame.do_op(op.getattr(w_obj, w_name)) - if w_obj.foldable() and w_name.foldable(): - obj, name = w_obj.value, w_name.value - try: - result = getattr(obj, name) - except Exception, e: - etype = e.__class__ - msg = "getattr(%s, %s) always raises %s: %s" % ( - obj, name, etype, e) - raise FlowingError(msg) - try: - return const(result) - except WrapException: - pass - return self.frame.do_op(op.getattr(w_obj, w_name)) - def import_name(self, name, glob=None, loc=None, frm=None, level=-1): try: mod = __import__(name, glob, loc, frm, level) @@ -235,8 +194,8 @@ assert isinstance(w_module, Constant) assert isinstance(w_name, Constant) # handle sys - if w_module in self.not_really_const: - const_w = self.not_really_const[w_module] + if w_module in NOT_REALLY_CONST: + const_w = NOT_REALLY_CONST[w_module] if w_name not in const_w: return self.frame.do_op(op.getattr(w_module, w_name)) try: diff --git a/rpython/flowspace/operation.py b/rpython/flowspace/operation.py --- a/rpython/flowspace/operation.py +++ b/rpython/flowspace/operation.py @@ -6,12 +6,29 @@ import __builtin__ import __future__ import operator +import sys from rpython.rlib.unroll import unrolling_iterable, _unroller from rpython.tool.sourcetools import compile2 from rpython.flowspace.model import (Constant, WrapException, const, Variable, SpaceOperation) from rpython.flowspace.specialcase import register_flow_sc +NOT_REALLY_CONST = { + Constant(sys): { + Constant('maxint'): True, + Constant('maxunicode'): True, + Constant('api_version'): True, + Constant('exit'): True, + Constant('exc_info'): True, + Constant('getrefcount'): True, + Constant('getdefaultencoding'): True, + # this is an incomplete list of true constants. + # if we add much more, a dedicated class + # might be considered for special objects. + } + } + + class _OpHolder(object): pass op = _OpHolder() @@ -218,7 +235,6 @@ add_operator('format', 2, 'format', pyfunc=unsupported) add_operator('len', 1, 'len', pyfunc=len, pure=True) add_operator('hash', 1, 'hash', pyfunc=hash) -add_operator('getattr', 2, 'getattr', pyfunc=getattr, pure=True) add_operator('setattr', 3, 'setattr', pyfunc=setattr) add_operator('delattr', 2, 'delattr', pyfunc=delattr) add_operator('getitem', 2, 'getitem', pure=True) @@ -323,13 +339,43 @@ return w_item op.next = Next +class GetAttr(HLOperation): + opname = 'getattr' + arity = 2 + can_overflow = False + canraise = [] + pyfunc = staticmethod(getattr) + + def constfold(self): + w_obj, w_name = self.args + # handling special things like sys + if (w_obj in NOT_REALLY_CONST and + w_name not in NOT_REALLY_CONST[w_obj]): + return + if w_obj.foldable() and w_name.foldable(): + obj, name = w_obj.value, w_name.value + try: + result = getattr(obj, name) + except Exception as e: + from rpython.flowspace.flowcontext import FlowingError + etype = e.__class__ + msg = "getattr(%s, %s) always raises %s: %s" % ( + obj, name, etype, e) + raise FlowingError(msg) + try: + return const(result) + except WrapException: + pass +op.getattr = GetAttr + + # Other functions that get directly translated to SpaceOperators func2op[type] = op.type func2op[operator.truth] = op.bool func2op[__builtin__.iter] = op.iter -if hasattr(__builtin__, 'next'): - func2op[__builtin__.next] = op.next +func2op[getattr] = op.getattr +func2op[__builtin__.next] = op.next for fn, oper in func2op.items(): register_flow_sc(fn)(oper.make_sc()) From noreply at buildbot.pypy.org Mon Sep 2 21:36:55 2013 From: noreply at buildbot.pypy.org (rlamy) Date: Mon, 2 Sep 2013 21:36:55 +0200 (CEST) Subject: [pypy-commit] pypy less-stringly-ops: Fix exception raising Message-ID: <20130902193655.17BC31C0962@cobra.cs.uni-duesseldorf.de> Author: Ronan Lamy Branch: less-stringly-ops Changeset: r66772:8d2a95a27c5e Date: 2013-09-01 14:19 +0100 http://bitbucket.org/pypy/pypy/changeset/8d2a95a27c5e/ Log: Fix exception raising diff --git a/rpython/flowspace/flowcontext.py b/rpython/flowspace/flowcontext.py --- a/rpython/flowspace/flowcontext.py +++ b/rpython/flowspace/flowcontext.py @@ -649,14 +649,18 @@ raise const(TypeError( "raise: no active exception to re-raise")) - w_value = space.w_None if nbargs >= 3: self.popvalue() if nbargs >= 2: w_value = self.popvalue() - if 1: w_type = self.popvalue() - operror = space.exc_from_raise(w_type, w_value) + operror = space.exc_from_raise(w_type, w_value) + else: + w_type = self.popvalue() + if isinstance(w_type, FSException): + operror = w_type + else: + operror = space.exc_from_raise(w_type, space.w_None) raise operror def IMPORT_NAME(self, nameindex): diff --git a/rpython/flowspace/test/test_objspace.py b/rpython/flowspace/test/test_objspace.py --- a/rpython/flowspace/test/test_objspace.py +++ b/rpython/flowspace/test/test_objspace.py @@ -387,6 +387,16 @@ assert x.startblock.exits[0].args == [ops[1].result, ops[0].result] assert x.startblock.exits[0].target is x.exceptblock + def test_simple_raise(self): + def f(): + raise ValueError('ouch') + x = self.codetest(f) + simplify_graph(x) + self.show(x) + ops = x.startblock.operations + assert ops[0].opname == 'simple_call' + assert ops[0].args == [Constant(ValueError), Constant('ouch')] + #__________________________________________________________ def raise2(msg): raise IndexError, msg From noreply at buildbot.pypy.org Mon Sep 2 21:36:56 2013 From: noreply at buildbot.pypy.org (rlamy) Date: Mon, 2 Sep 2013 21:36:56 +0200 (CEST) Subject: [pypy-commit] pypy less-stringly-ops: Use 'self' as the first argument of instance methods Message-ID: <20130902193656.48F481C0962@cobra.cs.uni-duesseldorf.de> Author: Ronan Lamy Branch: less-stringly-ops Changeset: r66773:72d64b5d667a Date: 2013-09-01 19:55 +0100 http://bitbucket.org/pypy/pypy/changeset/72d64b5d667a/ Log: Use 'self' as the first argument of instance methods diff --git a/rpython/annotator/unaryop.py b/rpython/annotator/unaryop.py --- a/rpython/annotator/unaryop.py +++ b/rpython/annotator/unaryop.py @@ -35,33 +35,33 @@ class __extend__(SomeObject): - def type(obj, *moreargs): + def type(self, *moreargs): if moreargs: raise Exception('type() called with more than one argument') r = SomeType() bk = getbookkeeper() - op = bk._find_current_op(opname="type", arity=1, pos=0, s_type=obj) + op = bk._find_current_op(opname="type", arity=1, pos=0, s_type=self) r.is_type_of = [op.args[0]] return r - def issubtype(obj, s_cls): - if hasattr(obj, 'is_type_of'): - vars = obj.is_type_of + def issubtype(self, s_cls): + if hasattr(self, 'is_type_of'): + vars = self.is_type_of annotator = getbookkeeper().annotator return builtin.builtin_isinstance(annotator.binding(vars[0]), s_cls, vars) - if obj.is_constant() and s_cls.is_constant(): - return immutablevalue(issubclass(obj.const, s_cls.const)) + if self.is_constant() and s_cls.is_constant(): + return immutablevalue(issubclass(self.const, s_cls.const)) return s_Bool - def len(obj): + def len(self): return SomeInteger(nonneg=True) - def bool_behavior(obj, s): - if obj.is_immutable_constant(): - s.const = bool(obj.const) + def bool_behavior(self, s): + if self.is_immutable_constant(): + s.const = bool(self.const) else: - s_len = obj.len() + s_len = self.len() if s_len.is_immutable_constant(): s.const = s_len.const > 0 @@ -80,83 +80,83 @@ r.set_knowntypedata(knowntypedata) return r - def hash(obj): + def hash(self): raise AnnotatorError("cannot use hash() in RPython") - def str(obj): - getbookkeeper().count('str', obj) + def str(self): + getbookkeeper().count('str', self) return SomeString() - def unicode(obj): - getbookkeeper().count('unicode', obj) + def unicode(self): + getbookkeeper().count('unicode', self) return SomeUnicodeString() - def repr(obj): - getbookkeeper().count('repr', obj) + def repr(self): + getbookkeeper().count('repr', self) return SomeString() - def hex(obj): - getbookkeeper().count('hex', obj) + def hex(self): + getbookkeeper().count('hex', self) return SomeString() - def oct(obj): - getbookkeeper().count('oct', obj) + def oct(self): + getbookkeeper().count('oct', self) return SomeString() - def id(obj): + def id(self): raise Exception("cannot use id() in RPython; " "see objectmodel.compute_xxx()") - def int(obj): + def int(self): return SomeInteger() - def float(obj): + def float(self): return SomeFloat() - def delattr(obj, s_attr): - if obj.__class__ != SomeObject or obj.knowntype != object: + def delattr(self, s_attr): + if self.__class__ != SomeObject or self.knowntype != object: getbookkeeper().warning( ("delattr on potentally non-SomeObjects is not RPythonic: delattr(%r,%r)" % - (obj, s_attr))) + (self, s_attr))) - def find_method(obj, name): + def find_method(self, name): "Look for a special-case implementation for the named method." try: - analyser = getattr(obj.__class__, 'method_' + name) + analyser = getattr(self.__class__, 'method_' + name) except AttributeError: return None else: - return SomeBuiltin(analyser, obj, name) + return SomeBuiltin(analyser, self, name) - def getattr(obj, s_attr): + def getattr(self, s_attr): # get a SomeBuiltin if the SomeObject has # a corresponding method to handle it if not s_attr.is_constant() or not isinstance(s_attr.const, str): raise AnnotatorError("getattr(%r, %r) has non-constant argument" - % (obj, s_attr)) + % (self, s_attr)) attr = s_attr.const - s_method = obj.find_method(attr) + s_method = self.find_method(attr) if s_method is not None: return s_method # if the SomeObject is itself a constant, allow reading its attrs - if obj.is_immutable_constant() and hasattr(obj.const, attr): - return immutablevalue(getattr(obj.const, attr)) - raise AnnotatorError("Cannot find attribute %r on %r" % (attr, obj)) + if self.is_immutable_constant() and hasattr(self.const, attr): + return immutablevalue(getattr(self.const, attr)) + raise AnnotatorError("Cannot find attribute %r on %r" % (attr, self)) getattr.can_only_throw = [] - def bind_callables_under(obj, classdef, name): - return obj # default unbound __get__ implementation + def bind_callables_under(self, classdef, name): + return self # default unbound __get__ implementation - def simple_call(obj, *args_s): - return obj.call(getbookkeeper().build_args("simple_call", args_s)) + def simple_call(self, *args_s): + return self.call(getbookkeeper().build_args("simple_call", args_s)) - def call_args(obj, *args_s): - return obj.call(getbookkeeper().build_args("call_args", args_s)) + def call_args(self, *args_s): + return self.call(getbookkeeper().build_args("call_args", args_s)) - def call(obj, args, implicit_init=False): + def call(self, args, implicit_init=False): raise AnnotatorError("Cannot prove that the object is callable") - def op_contains(obj, s_element): + def op_contains(self, s_element): return s_Bool op_contains.can_only_throw = [] @@ -165,10 +165,10 @@ class __extend__(SomeFloat): - def pos(flt): - return flt + def pos(self): + return self - def neg(flt): + def neg(self): return SomeFloat() abs = neg @@ -233,105 +233,105 @@ class __extend__(SomeTuple): - def len(tup): - return immutablevalue(len(tup.items)) + def len(self): + return immutablevalue(len(self.items)) - def iter(tup): - getbookkeeper().count("tuple_iter", tup) - return SomeIterator(tup) + def iter(self): + getbookkeeper().count("tuple_iter", self) + return SomeIterator(self) iter.can_only_throw = [] - def getanyitem(tup): - return unionof(*tup.items) + def getanyitem(self): + return unionof(*self.items) - def getslice(tup, s_start, s_stop): + def getslice(self, s_start, s_stop): assert s_start.is_immutable_constant(),"tuple slicing: needs constants" assert s_stop.is_immutable_constant(), "tuple slicing: needs constants" - items = tup.items[s_start.const:s_stop.const] + items = self.items[s_start.const:s_stop.const] return SomeTuple(items) class __extend__(SomeList): - def method_append(lst, s_value): - lst.listdef.resize() - lst.listdef.generalize(s_value) + def method_append(self, s_value): + self.listdef.resize() + self.listdef.generalize(s_value) - def method_extend(lst, s_iterable): - lst.listdef.resize() + def method_extend(self, s_iterable): + self.listdef.resize() if isinstance(s_iterable, SomeList): # unify the two lists - lst.listdef.agree(s_iterable.listdef) + self.listdef.agree(s_iterable.listdef) else: s_iter = s_iterable.iter() - lst.method_append(s_iter.next()) + self.method_append(s_iter.next()) - def method_reverse(lst): - lst.listdef.mutate() + def method_reverse(self): + self.listdef.mutate() - def method_insert(lst, s_index, s_value): - lst.method_append(s_value) + def method_insert(self, s_index, s_value): + self.method_append(s_value) - def method_remove(lst, s_value): - lst.listdef.resize() - lst.listdef.generalize(s_value) + def method_remove(self, s_value): + self.listdef.resize() + self.listdef.generalize(s_value) - def method_pop(lst, s_index=None): - lst.listdef.resize() - return lst.listdef.read_item() + def method_pop(self, s_index=None): + self.listdef.resize() + return self.listdef.read_item() method_pop.can_only_throw = [IndexError] - def method_index(lst, s_value): + def method_index(self, s_value): getbookkeeper().count("list_index") - lst.listdef.generalize(s_value) + self.listdef.generalize(s_value) return SomeInteger(nonneg=True) - def len(lst): - s_item = lst.listdef.read_item() + def len(self): + s_item = self.listdef.read_item() if isinstance(s_item, SomeImpossibleValue): return immutablevalue(0) - return SomeObject.len(lst) + return SomeObject.len(self) - def iter(lst): - return SomeIterator(lst) + def iter(self): + return SomeIterator(self) iter.can_only_throw = [] - def getanyitem(lst): - return lst.listdef.read_item() + def getanyitem(self): + return self.listdef.read_item() - def op_contains(lst, s_element): - lst.listdef.generalize(s_element) + def op_contains(self, s_element): + self.listdef.generalize(s_element) return s_Bool op_contains.can_only_throw = [] - def hint(lst, *args_s): + def hint(self, *args_s): hints = args_s[-1].const if 'maxlength' in hints: # only for iteration over lists or dicts at the moment, # not over an iterator object (because it has no known length) s_iterable = args_s[0] if isinstance(s_iterable, (SomeList, SomeDict)): - lst = SomeList(lst.listdef) # create a fresh copy - lst.listdef.resize() - lst.listdef.listitem.hint_maxlength = True + self = SomeList(self.listdef) # create a fresh copy + self.listdef.resize() + self.listdef.listitem.hint_maxlength = True elif 'fence' in hints: - lst = lst.listdef.offspring() - return lst + self = self.listdef.offspring() + return self - def getslice(lst, s_start, s_stop): + def getslice(self, s_start, s_stop): check_negative_slice(s_start, s_stop) - return lst.listdef.offspring() + return self.listdef.offspring() - def setslice(lst, s_start, s_stop, s_iterable): + def setslice(self, s_start, s_stop, s_iterable): check_negative_slice(s_start, s_stop) if not isinstance(s_iterable, SomeList): raise Exception("list[start:stop] = x: x must be a list") - lst.listdef.mutate() - lst.listdef.agree(s_iterable.listdef) + self.listdef.mutate() + self.listdef.agree(s_iterable.listdef) # note that setslice is not allowed to resize a list in RPython - def delslice(lst, s_start, s_stop): + def delslice(self, s_start, s_stop): check_negative_slice(s_start, s_stop) - lst.listdef.resize() + self.listdef.resize() def check_negative_slice(s_start, s_stop): if isinstance(s_start, SomeInteger) and not s_start.nonneg: @@ -343,29 +343,29 @@ class __extend__(SomeDict): - def _is_empty(dct): - s_key = dct.dictdef.read_key() - s_value = dct.dictdef.read_value() + def _is_empty(self): + s_key = self.dictdef.read_key() + s_value = self.dictdef.read_value() return (isinstance(s_key, SomeImpossibleValue) or isinstance(s_value, SomeImpossibleValue)) - def len(dct): - if dct._is_empty(): + def len(self): + if self._is_empty(): return immutablevalue(0) - return SomeObject.len(dct) + return SomeObject.len(self) - def iter(dct): - return SomeIterator(dct) + def iter(self): + return SomeIterator(self) iter.can_only_throw = [] - def getanyitem(dct, variant='keys'): + def getanyitem(self, variant='keys'): if variant == 'keys': - return dct.dictdef.read_key() + return self.dictdef.read_key() elif variant == 'values': - return dct.dictdef.read_value() + return self.dictdef.read_value() elif variant == 'items': - s_key = dct.dictdef.read_key() - s_value = dct.dictdef.read_value() + s_key = self.dictdef.read_key() + s_value = self.dictdef.read_value() if (isinstance(s_key, SomeImpossibleValue) or isinstance(s_value, SomeImpossibleValue)): return s_ImpossibleValue @@ -374,59 +374,59 @@ else: raise ValueError - def method_get(dct, key, dfl): - dct.dictdef.generalize_key(key) - dct.dictdef.generalize_value(dfl) - return dct.dictdef.read_value() + def method_get(self, key, dfl): + self.dictdef.generalize_key(key) + self.dictdef.generalize_value(dfl) + return self.dictdef.read_value() method_setdefault = method_get - def method_copy(dct): - return SomeDict(dct.dictdef) + def method_copy(self): + return SomeDict(self.dictdef) def method_update(dct1, dct2): if s_None.contains(dct2): return SomeImpossibleValue() dct1.dictdef.union(dct2.dictdef) - def method_keys(dct): - return getbookkeeper().newlist(dct.dictdef.read_key()) + def method_keys(self): + return getbookkeeper().newlist(self.dictdef.read_key()) - def method_values(dct): - return getbookkeeper().newlist(dct.dictdef.read_value()) + def method_values(self): + return getbookkeeper().newlist(self.dictdef.read_value()) - def method_items(dct): - return getbookkeeper().newlist(dct.getanyitem('items')) + def method_items(self): + return getbookkeeper().newlist(self.getanyitem('items')) - def method_iterkeys(dct): - return SomeIterator(dct, 'keys') + def method_iterkeys(self): + return SomeIterator(self, 'keys') - def method_itervalues(dct): - return SomeIterator(dct, 'values') + def method_itervalues(self): + return SomeIterator(self, 'values') - def method_iteritems(dct): - return SomeIterator(dct, 'items') + def method_iteritems(self): + return SomeIterator(self, 'items') - def method_clear(dct): + def method_clear(self): pass - def method_popitem(dct): - return dct.getanyitem('items') + def method_popitem(self): + return self.getanyitem('items') - def method_pop(dct, s_key, s_dfl=None): - dct.dictdef.generalize_key(s_key) + def method_pop(self, s_key, s_dfl=None): + self.dictdef.generalize_key(s_key) if s_dfl is not None: - dct.dictdef.generalize_value(s_dfl) - return dct.dictdef.read_value() + self.dictdef.generalize_value(s_dfl) + return self.dictdef.read_value() - def _can_only_throw(dic, *ignore): - if dic.dictdef.dictkey.custom_eq_hash: + def _can_only_throw(self, *ignore): + if self.dictdef.dictkey.custom_eq_hash: return None # r_dict: can throw anything return [] # else: no possible exception - def op_contains(dct, s_element): - dct.dictdef.generalize_key(s_element) - if dct._is_empty(): + def op_contains(self, s_element): + self.dictdef.generalize_key(s_element) + if self._is_empty(): s_bool = SomeBool() s_bool.const = False return s_bool @@ -437,91 +437,91 @@ class __extend__(SomeString, SomeUnicodeString): - def method_startswith(str, frag): - if str.is_constant() and frag.is_constant(): - return immutablevalue(str.const.startswith(frag.const)) + def method_startswith(self, frag): + if self.is_constant() and frag.is_constant(): + return immutablevalue(self.const.startswith(frag.const)) return s_Bool - def method_endswith(str, frag): - if str.is_constant() and frag.is_constant(): - return immutablevalue(str.const.endswith(frag.const)) + def method_endswith(self, frag): + if self.is_constant() and frag.is_constant(): + return immutablevalue(self.const.endswith(frag.const)) return s_Bool - def method_find(str, frag, start=None, end=None): + def method_find(self, frag, start=None, end=None): return SomeInteger() - def method_rfind(str, frag, start=None, end=None): + def method_rfind(self, frag, start=None, end=None): return SomeInteger() - def method_count(str, frag, start=None, end=None): + def method_count(self, frag, start=None, end=None): return SomeInteger(nonneg=True) - def method_strip(str, chr): - return str.basestringclass(no_nul=str.no_nul) + def method_strip(self, chr): + return self.basestringclass(no_nul=self.no_nul) - def method_lstrip(str, chr): - return str.basestringclass(no_nul=str.no_nul) + def method_lstrip(self, chr): + return self.basestringclass(no_nul=self.no_nul) - def method_rstrip(str, chr): - return str.basestringclass(no_nul=str.no_nul) + def method_rstrip(self, chr): + return self.basestringclass(no_nul=self.no_nul) - def method_join(str, s_list): + def method_join(self, s_list): if s_None.contains(s_list): return SomeImpossibleValue() - getbookkeeper().count("str_join", str) + getbookkeeper().count("str_join", self) s_item = s_list.listdef.read_item() if s_None.contains(s_item): - if isinstance(str, SomeUnicodeString): + if isinstance(self, SomeUnicodeString): return immutablevalue(u"") return immutablevalue("") - no_nul = str.no_nul and s_item.no_nul - return str.basestringclass(no_nul=no_nul) + no_nul = self.no_nul and s_item.no_nul + return self.basestringclass(no_nul=no_nul) - def iter(str): - return SomeIterator(str) + def iter(self): + return SomeIterator(self) iter.can_only_throw = [] - def getanyitem(str): - return str.basecharclass() + def getanyitem(self): + return self.basecharclass() - def method_split(str, patt, max=-1): - getbookkeeper().count("str_split", str, patt) + def method_split(self, patt, max=-1): + getbookkeeper().count("str_split", self, patt) 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) + no_nul = self.no_nul + s_item = self.basestringclass(no_nul=no_nul) return getbookkeeper().newlist(s_item) - def method_rsplit(str, patt, max=-1): - getbookkeeper().count("str_rsplit", str, patt) - s_item = str.basestringclass(no_nul=str.no_nul) + def method_rsplit(self, patt, max=-1): + getbookkeeper().count("str_rsplit", self, patt) + s_item = self.basestringclass(no_nul=self.no_nul) return getbookkeeper().newlist(s_item) - def method_replace(str, s1, s2): - return str.basestringclass(no_nul=str.no_nul and s2.no_nul) + def method_replace(self, s1, s2): + return self.basestringclass(no_nul=self.no_nul and s2.no_nul) - def getslice(str, s_start, s_stop): + def getslice(self, s_start, s_stop): check_negative_slice(s_start, s_stop) - result = str.basestringclass(no_nul=str.no_nul) + result = self.basestringclass(no_nul=self.no_nul) return result - def op_contains(str, s_element): + def op_contains(self, 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) + op = bk._find_current_op(opname="contains", arity=2, pos=0, s_type=self) knowntypedata = {} - add_knowntypedata(knowntypedata, False, [op.args[0]], str.nonnulify()) + add_knowntypedata(knowntypedata, False, [op.args[0]], self.nonnulify()) r.set_knowntypedata(knowntypedata) return r else: - return SomeObject.op_contains(str, s_element) + return SomeObject.op_contains(self, s_element) op_contains.can_only_throw = [] class __extend__(SomeUnicodeString): - def method_encode(uni, s_enc): + def method_encode(self, s_enc): if not s_enc.is_constant(): raise AnnotatorError("Non-constant encoding not supported") enc = s_enc.const @@ -532,29 +532,29 @@ class __extend__(SomeString): - def method_isdigit(str): + def method_isdigit(self): return s_Bool - def method_isalpha(str): + def method_isalpha(self): return s_Bool - def method_isalnum(str): + def method_isalnum(self): return s_Bool - def method_upper(str): + def method_upper(self): return SomeString() - def method_lower(str): + def method_lower(self): return SomeString() - def method_splitlines(str, s_keep_newlines=None): - s_list = getbookkeeper().newlist(str.basestringclass()) + def method_splitlines(self, s_keep_newlines=None): + s_list = getbookkeeper().newlist(self.basestringclass()) # Force the list to be resizable because ll_splitlines doesn't # preallocate the list. s_list.listdef.listitem.resize() return s_list - def method_decode(str, s_enc): + def method_decode(self, s_enc): if not s_enc.is_constant(): raise AnnotatorError("Non-constant encoding not supported") enc = s_enc.const @@ -565,96 +565,96 @@ class __extend__(SomeChar, SomeUnicodeCodePoint): - def len(chr): + def len(self): return immutablevalue(1) - def ord(str): + def ord(self): return SomeInteger(nonneg=True) class __extend__(SomeChar): - def method_isspace(chr): + def method_isspace(self): return s_Bool - def method_isalnum(chr): + def method_isalnum(self): return s_Bool - def method_islower(chr): + def method_islower(self): return s_Bool - def method_isupper(chr): + def method_isupper(self): return s_Bool - def method_lower(chr): - return chr + def method_lower(self): + return self - def method_upper(chr): - return chr + def method_upper(self): + return self class __extend__(SomeIterator): - def iter(itr): - return itr + def iter(self): + return self iter.can_only_throw = [] - def _can_only_throw(itr): + def _can_only_throw(self): can_throw = [StopIteration] - if isinstance(itr.s_container, SomeDict): + if isinstance(self.s_container, SomeDict): can_throw.append(RuntimeError) return can_throw - def next(itr): - if itr.variant == ("enumerate",): - s_item = itr.s_container.getanyitem() + def next(self): + if self.variant == ("enumerate",): + s_item = self.s_container.getanyitem() return SomeTuple((SomeInteger(nonneg=True), s_item)) - variant = itr.variant + variant = self.variant if variant == ("reversed",): variant = () - return itr.s_container.getanyitem(*variant) + return self.s_container.getanyitem(*variant) next.can_only_throw = _can_only_throw method_next = next class __extend__(SomeInstance): - def _true_getattr(ins, attr): + def _true_getattr(self, attr): if attr == '__class__': - return ins.classdef.read_attr__class__() - attrdef = ins.classdef.find_attribute(attr) + return self.classdef.read_attr__class__() + attrdef = self.classdef.find_attribute(attr) position = getbookkeeper().position_key attrdef.read_locations[position] = True s_result = attrdef.getvalue() # hack: if s_result is a set of methods, discard the ones - # that can't possibly apply to an instance of ins.classdef. + # that can't possibly apply to an instance of self.classdef. # XXX do it more nicely if isinstance(s_result, SomePBC): - s_result = ins.classdef.lookup_filter(s_result, attr, - ins.flags) + s_result = self.classdef.lookup_filter(s_result, attr, + self.flags) elif isinstance(s_result, SomeImpossibleValue): - ins.classdef.check_missing_attribute_update(attr) + self.classdef.check_missing_attribute_update(attr) # blocking is harmless if the attribute is explicitly listed # in the class or a parent class. - for basedef in ins.classdef.getmro(): + for basedef in self.classdef.getmro(): if basedef.classdesc.all_enforced_attrs is not None: if attr in basedef.classdesc.all_enforced_attrs: raise HarmlesslyBlocked("get enforced attr") elif isinstance(s_result, SomeList): - s_result = ins.classdef.classdesc.maybe_return_immutable_list( + s_result = self.classdef.classdesc.maybe_return_immutable_list( attr, s_result) return s_result - def getattr(ins, s_attr): + def getattr(self, s_attr): if s_attr.is_constant() and isinstance(s_attr.const, str): attr = s_attr.const - return ins._true_getattr(attr) + return self._true_getattr(attr) raise AnnotatorError("A variable argument to getattr is not RPython") getattr.can_only_throw = [] - def setattr(ins, s_attr, s_value): + def setattr(self, s_attr, s_value): if s_attr.is_constant() and isinstance(s_attr.const, str): attr = s_attr.const # find the (possibly parent) class where this attr is defined - clsdef = ins.classdef.locate_attribute(attr) + clsdef = self.classdef.locate_attribute(attr) attrdef = clsdef.attrs[attr] attrdef.modified(clsdef) @@ -664,83 +664,83 @@ # create or update the attribute in clsdef clsdef.generalize_attr(attr, s_value) - def bool_behavior(ins, s): - if not ins.can_be_None: + def bool_behavior(self, s): + if not self.can_be_None: s.const = True - def iter(ins): - s_iterable = ins._true_getattr('__iter__') + def iter(self): + s_iterable = self._true_getattr('__iter__') bk = getbookkeeper() # record for calltables bk.emulate_pbc_call(bk.position_key, s_iterable, []) return s_iterable.call(bk.build_args("simple_call", [])) - def next(ins): - s_next = ins._true_getattr('next') + def next(self): + s_next = self._true_getattr('next') bk = getbookkeeper() # record for calltables bk.emulate_pbc_call(bk.position_key, s_next, []) return s_next.call(bk.build_args("simple_call", [])) class __extend__(SomeBuiltin): - def _can_only_throw(bltn, *args): - analyser_func = getattr(bltn.analyser, 'im_func', None) + def _can_only_throw(self, *args): + analyser_func = getattr(self.analyser, 'im_func', None) can_only_throw = getattr(analyser_func, 'can_only_throw', None) if can_only_throw is None or isinstance(can_only_throw, list): return can_only_throw - if bltn.s_self is not None: - return can_only_throw(bltn.s_self, *args) + if self.s_self is not None: + return can_only_throw(self.s_self, *args) else: return can_only_throw(*args) - def simple_call(bltn, *args): - if bltn.s_self is not None: - return bltn.analyser(bltn.s_self, *args) + def simple_call(self, *args): + if self.s_self is not None: + return self.analyser(self.s_self, *args) else: - if bltn.methodname: - getbookkeeper().count(bltn.methodname.replace('.', '_'), *args) - return bltn.analyser(*args) + if self.methodname: + getbookkeeper().count(self.methodname.replace('.', '_'), *args) + return self.analyser(*args) simple_call.can_only_throw = _can_only_throw - def call(bltn, args, implicit_init=False): + def call(self, args, implicit_init=False): args_s, kwds = args.unpack() # prefix keyword arguments with 's_' kwds_s = {} for key, s_value in kwds.items(): kwds_s['s_'+key] = s_value - if bltn.s_self is not None: - return bltn.analyser(bltn.s_self, *args_s, **kwds_s) + if self.s_self is not None: + return self.analyser(self.s_self, *args_s, **kwds_s) else: - return bltn.analyser(*args_s, **kwds_s) + return self.analyser(*args_s, **kwds_s) class __extend__(SomePBC): - def getattr(pbc, s_attr): + def getattr(self, s_attr): bookkeeper = getbookkeeper() - return bookkeeper.pbc_getattr(pbc, s_attr) + return bookkeeper.pbc_getattr(self, s_attr) getattr.can_only_throw = [] - def setattr(pbc, s_attr, s_value): - if not pbc.isNone(): + def setattr(self, s_attr, s_value): + if not self.isNone(): raise AnnotatorError("Cannot modify attribute of a pre-built constant") - def call(pbc, args): + def call(self, args): bookkeeper = getbookkeeper() - return bookkeeper.pbc_call(pbc, args) + return bookkeeper.pbc_call(self, args) - def bind_callables_under(pbc, classdef, name): - d = [desc.bind_under(classdef, name) for desc in pbc.descriptions] - return SomePBC(d, can_be_None=pbc.can_be_None) + def bind_callables_under(self, classdef, name): + d = [desc.bind_under(classdef, name) for desc in self.descriptions] + return SomePBC(d, can_be_None=self.can_be_None) - def bool_behavior(pbc, s): - if pbc.isNone(): + def bool_behavior(self, s): + if self.isNone(): s.const = False - elif not pbc.can_be_None: + elif not self.can_be_None: s.const = True - def len(pbc): - if pbc.isNone(): + def len(self): + if self.isNone(): # this None could later be generalized into an empty list, # whose length is the constant 0; so let's tentatively answer 0. return immutablevalue(0) @@ -754,9 +754,9 @@ class __extend__(SomePtr): - def getattr(p, s_attr): - assert s_attr.is_constant(), "getattr on ptr %r with non-constant field-name" % p.ll_ptrtype - example = p.ll_ptrtype._example() + def getattr(self, s_attr): + assert s_attr.is_constant(), "getattr on ptr %r with non-constant field-name" % self.ll_ptrtype + example = self.ll_ptrtype._example() try: v = example._lookup_adtmeth(s_attr.const) except AttributeError: @@ -771,48 +771,48 @@ return getbookkeeper().immutablevalue(v) getattr.can_only_throw = [] - def len(p): - length = p.ll_ptrtype._example()._fixedlength() + def len(self): + length = self.ll_ptrtype._example()._fixedlength() if length is None: - return SomeObject.len(p) + return SomeObject.len(self) else: return immutablevalue(length) - def setattr(p, s_attr, s_value): # just doing checking - assert s_attr.is_constant(), "setattr on ptr %r with non-constant field-name" % p.ll_ptrtype - example = p.ll_ptrtype._example() + def setattr(self, s_attr, s_value): # just doing checking + assert s_attr.is_constant(), "setattr on ptr %r with non-constant field-name" % self.ll_ptrtype + example = self.ll_ptrtype._example() if getattr(example, s_attr.const) is not None: # ignore Void s_value v_lltype = annotation_to_lltype(s_value) setattr(example, s_attr.const, v_lltype._defl()) - def call(p, args): + def call(self, args): args_s, kwds_s = args.unpack() if kwds_s: raise Exception("keyword arguments to call to a low-level fn ptr") info = 'argument to ll function pointer call' llargs = [annotation_to_lltype(s_arg,info)._defl() for s_arg in args_s] - v = p.ll_ptrtype._example()(*llargs) + v = self.ll_ptrtype._example()(*llargs) return ll_to_annotation(v) - def bool(p): + def bool(self): return s_Bool class __extend__(SomeLLADTMeth): - def call(adtmeth, args): + def call(self, args): bookkeeper = getbookkeeper() - s_func = bookkeeper.immutablevalue(adtmeth.func) - return s_func.call(args.prepend(lltype_to_annotation(adtmeth.ll_ptrtype))) + s_func = bookkeeper.immutablevalue(self.func) + return s_func.call(args.prepend(lltype_to_annotation(self.ll_ptrtype))) #_________________________________________ # weakrefs class __extend__(SomeWeakRef): - def simple_call(s_wrf): - if s_wrf.classdef is None: + def simple_call(self): + if self.classdef is None: return s_None # known to be a dead weakref else: - return SomeInstance(s_wrf.classdef, can_be_None=True) + return SomeInstance(self.classdef, can_be_None=True) #_________________________________________ # memory addresses @@ -820,7 +820,7 @@ from rpython.rtyper.lltypesystem import llmemory class __extend__(SomeAddress): - def getattr(s_addr, s_attr): + def getattr(self, s_attr): assert s_attr.is_constant() assert isinstance(s_attr, SomeString) assert s_attr.const in llmemory.supported_access_types @@ -828,5 +828,5 @@ llmemory.supported_access_types[s_attr.const]) getattr.can_only_throw = [] - def bool(s_addr): + def bool(self): return s_Bool From noreply at buildbot.pypy.org Mon Sep 2 21:36:57 2013 From: noreply at buildbot.pypy.org (rlamy) Date: Mon, 2 Sep 2013 21:36:57 +0200 (CEST) Subject: [pypy-commit] pypy less-stringly-ops: Add annotation SomeConstantType: Message-ID: <20130902193657.842EB1C0962@cobra.cs.uni-duesseldorf.de> Author: Ronan Lamy Branch: less-stringly-ops Changeset: r66774:2c9d5c1c85d7 Date: 2013-09-02 20:33 +0100 http://bitbucket.org/pypy/pypy/changeset/2c9d5c1c85d7/ Log: Add annotation SomeConstantType: this is a SomePBC subclass that can be unified with SomeTypes. diff --git a/rpython/annotator/binaryop.py b/rpython/annotator/binaryop.py --- a/rpython/annotator/binaryop.py +++ b/rpython/annotator/binaryop.py @@ -5,18 +5,14 @@ import py import operator from rpython.tool.pairtype import pair, pairtype -from rpython.annotator.model import SomeObject, SomeInteger, SomeBool, s_Bool -from rpython.annotator.model import SomeString, SomeChar, SomeList, SomeDict -from rpython.annotator.model import SomeUnicodeCodePoint, SomeUnicodeString -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 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 ( + SomeObject, SomeInteger, SomeBool, s_Bool, SomeString, SomeChar, SomeList, + SomeDict, SomeUnicodeCodePoint, SomeUnicodeString, SomeTuple, + SomeImpossibleValue, s_ImpossibleValue, SomeInstance, SomeBuiltin, + SomeIterator, SomePBC, SomeFloat, s_None, SomeByteArray, SomeWeakRef, + SomeAddress, SomeTypedAddressAccess, SomeSingleFloat, SomeLongFloat, + SomeType, SomeConstantType, unionof, UnionError, missing_operation, + read_can_only_throw, add_knowntypedata, merge_knowntypedata,) from rpython.annotator.bookkeeper import getbookkeeper from rpython.flowspace.model import Variable, Constant from rpython.rlib import rarithmetic @@ -196,7 +192,9 @@ getitem_key = getitem_idx_key -class __extend__(pairtype(SomeType, SomeType)): +class __extend__(pairtype(SomeType, SomeType), + pairtype(SomeType, SomeConstantType), + pairtype(SomeConstantType, SomeType),): def union((obj1, obj2)): result = SomeType() 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 @@ SomeBuiltin, SomePBC, SomeInteger, TLS, SomeAddress, SomeUnicodeCodePoint, s_None, s_ImpossibleValue, SomeLLADTMeth, SomeBool, SomeTuple, SomeImpossibleValue, SomeUnicodeString, SomeList, HarmlesslyBlocked, - SomeWeakRef, lltype_to_annotation, SomeType, SomeByteArray) + SomeWeakRef, lltype_to_annotation, SomeType, SomeByteArray, SomeConstantType) from rpython.annotator.classdef import InstanceSource, ClassDef from rpython.annotator.listdef import ListDef, ListItem from rpython.annotator.dictdef import DictDef @@ -432,11 +432,7 @@ elif isinstance(x, llmemory.fakeaddress): result = SomeAddress() elif tp is type: - if (x is type(None) or # add cases here if needed - x.__module__ == 'rpython.rtyper.lltypesystem.lltype'): - result = SomeType() - else: - result = SomePBC([self.getdesc(x)]) + result = SomeConstantType(x, self) elif callable(x): if hasattr(x, 'im_self') and hasattr(x, 'im_func'): # on top of PyPy, for cases like 'l.append' where 'l' is a diff --git a/rpython/annotator/model.py b/rpython/annotator/model.py --- a/rpython/annotator/model.py +++ b/rpython/annotator/model.py @@ -486,6 +486,14 @@ else: return kt.__name__ +class SomeConstantType(SomePBC): + can_be_None = False + subset_of = None + def __init__(self, x, bk): + self.descriptions = set([bk.getdesc(x)]) + self.knowntype = type(x) + self.const = x + class SomeBuiltin(SomeObject): "Stands for a built-in function or method with special-cased analysis." From noreply at buildbot.pypy.org Mon Sep 2 21:37:01 2013 From: noreply at buildbot.pypy.org (rlamy) Date: Mon, 2 Sep 2013 21:37:01 +0200 (CEST) Subject: [pypy-commit] pypy less-stringly-ops: hg merge default Message-ID: <20130902193701.51F9C1C0962@cobra.cs.uni-duesseldorf.de> Author: Ronan Lamy Branch: less-stringly-ops Changeset: r66775:2f5fa1d65fff Date: 2013-09-02 20:35 +0100 http://bitbucket.org/pypy/pypy/changeset/2f5fa1d65fff/ Log: hg merge default diff too long, truncating to 2000 out of 2070 lines diff --git a/lib-python/2.7/uuid.py b/lib-python/2.7/uuid.py --- a/lib-python/2.7/uuid.py +++ b/lib-python/2.7/uuid.py @@ -44,6 +44,8 @@ UUID('00010203-0405-0607-0809-0a0b0c0d0e0f') """ +import struct + __author__ = 'Ka-Ping Yee ' RESERVED_NCS, RFC_4122, RESERVED_MICROSOFT, RESERVED_FUTURE = [ @@ -125,25 +127,38 @@ overriding the given 'hex', 'bytes', 'bytes_le', 'fields', or 'int'. """ - if [hex, bytes, bytes_le, fields, int].count(None) != 4: - raise TypeError('need one of hex, bytes, bytes_le, fields, or int') if hex is not None: + if (bytes is not None or bytes_le is not None or fields is not None + or int is not None): + raise TypeError('if the hex argument is given, bytes, bytes_le, fields,' + ' and int need to be None') hex = hex.replace('urn:', '').replace('uuid:', '') hex = hex.strip('{}').replace('-', '') if len(hex) != 32: raise ValueError('badly formed hexadecimal UUID string') int = long(hex, 16) - if bytes_le is not None: + elif bytes_le is not None: + if bytes is not None or fields is not None or int is not None: + raise TypeError('if the bytes_le argument is given, bytes, fields,' + ' and int need to be None') if len(bytes_le) != 16: raise ValueError('bytes_le is not a 16-char string') bytes = (bytes_le[3] + bytes_le[2] + bytes_le[1] + bytes_le[0] + bytes_le[5] + bytes_le[4] + bytes_le[7] + bytes_le[6] + bytes_le[8:]) - if bytes is not None: + int = (struct.unpack('>Q', bytes[:8])[0] << 64 | + struct.unpack('>Q', bytes[8:])[0]) + elif bytes is not None: + if fields is not None or int is not None: + raise TypeError('if the bytes argument is given, fields' + ' and int need to be None') if len(bytes) != 16: raise ValueError('bytes is not a 16-char string') - int = long(('%02x'*16) % tuple(map(ord, bytes)), 16) - if fields is not None: + int = (struct.unpack('>Q', bytes[:8])[0] << 64 | + struct.unpack('>Q', bytes[8:])[0]) + elif fields is not None: + if int is not None: + raise TypeError('if the fields argument is given, int needs to be None') if len(fields) != 6: raise ValueError('fields is not a 6-tuple') (time_low, time_mid, time_hi_version, @@ -163,9 +178,12 @@ clock_seq = (clock_seq_hi_variant << 8L) | clock_seq_low int = ((time_low << 96L) | (time_mid << 80L) | (time_hi_version << 64L) | (clock_seq << 48L) | node) - if int is not None: + elif int is not None: if not 0 <= int < 1<<128L: raise ValueError('int is out of range (need a 128-bit value)') + else: + raise TypeError('one of hex, bytes, bytes_le, fields,' + ' or int need to be not None') if version is not None: if not 1 <= version <= 5: raise ValueError('illegal version number') @@ -175,7 +193,7 @@ # Set the version number. int &= ~(0xf000 << 64L) int |= version << 76L - self.__dict__['int'] = int + object.__setattr__(self, 'int', int) def __cmp__(self, other): if isinstance(other, UUID): diff --git a/lib_pypy/datetime.py b/lib_pypy/datetime.py --- a/lib_pypy/datetime.py +++ b/lib_pypy/datetime.py @@ -40,9 +40,9 @@ # for all computations. See the book for algorithms for converting between # proleptic Gregorian ordinals and many other calendar systems. -_DAYS_IN_MONTH = [None, 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31] +_DAYS_IN_MONTH = [-1, 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31] -_DAYS_BEFORE_MONTH = [None] +_DAYS_BEFORE_MONTH = [-1] dbm = 0 for dim in _DAYS_IN_MONTH[1:]: _DAYS_BEFORE_MONTH.append(dbm) diff --git a/pypy/config/pypyoption.py b/pypy/config/pypyoption.py --- a/pypy/config/pypyoption.py +++ b/pypy/config/pypyoption.py @@ -127,11 +127,6 @@ pypy_optiondescription = OptionDescription("objspace", "Object Space Options", [ - OptionDescription("opcodes", "opcodes to enable in the interpreter", [ - BoolOption("CALL_METHOD", "emit a special bytecode for expr.name()", - default=False), - ]), - OptionDescription("usemodules", "Which Modules should be used", [ BoolOption(modname, "use module %s" % (modname, ), default=modname in default_modules, @@ -259,9 +254,6 @@ BoolOption("optimized_int_add", "special case the addition of two integers in BINARY_ADD", default=False), - BoolOption("optimized_comparison_op", - "special case the comparison of integers", - default=False), BoolOption("optimized_list_getitem", "special case the 'list[integer]' expressions", default=False), @@ -307,7 +299,6 @@ # all the good optimizations for PyPy should be listed here if level in ['2', '3', 'jit']: - config.objspace.opcodes.suggest(CALL_METHOD=True) config.objspace.std.suggest(withrangelist=True) config.objspace.std.suggest(withmethodcache=True) config.objspace.std.suggest(withprebuiltchar=True) diff --git a/pypy/doc/config/objspace.opcodes.CALL_METHOD.txt b/pypy/doc/config/objspace.opcodes.CALL_METHOD.txt deleted file mode 100644 --- a/pypy/doc/config/objspace.opcodes.CALL_METHOD.txt +++ /dev/null @@ -1,10 +0,0 @@ -Enable a pair of bytecodes that speed up method calls. -See ``pypy.interpreter.callmethod`` for a description. - -The goal is to avoid creating the bound method object in the common -case. So far, this only works for calls with no keyword, no ``*arg`` -and no ``**arg`` but it would be easy to extend. - -For more information, see the section in `Standard Interpreter Optimizations`_. - -.. _`Standard Interpreter Optimizations`: ../interpreter-optimizations.html#lookup-method-call-method diff --git a/pypy/doc/config/objspace.opcodes.txt b/pypy/doc/config/objspace.opcodes.txt deleted file mode 100644 --- a/pypy/doc/config/objspace.opcodes.txt +++ /dev/null @@ -1,1 +0,0 @@ -.. intentionally empty 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 @@ -198,9 +198,6 @@ if it is not None, then it is considered to be an additional first argument in the call to the *im_func* object from the stack. -You can enable this feature with the :config:`objspace.opcodes.CALL_METHOD` -option. - .. more here? Overall Effects diff --git a/pypy/doc/tool/makecontributor.py b/pypy/doc/tool/makecontributor.py --- a/pypy/doc/tool/makecontributor.py +++ b/pypy/doc/tool/makecontributor.py @@ -60,6 +60,11 @@ 'Roberto De Ioris': ['roberto at mrspurr'], 'Sven Hager': ['hager'], 'Tomo Cocoa': ['cocoatomo'], + 'Romain Guillebert': ['rguillebert', 'rguillbert', 'romain', 'Guillebert Romain'], + 'Ronan Lamy': ['ronan'], + 'Edd Barrett': ['edd'], + 'Manuel Jacob': ['mjacob'], + 'Rami Chowdhury': ['necaris'], } alias_map = {} @@ -80,7 +85,8 @@ if not match: return set() ignore_words = ['around', 'consulting', 'yesterday', 'for a bit', 'thanks', - 'in-progress', 'bits of', 'even a little', 'floating',] + 'in-progress', 'bits of', 'even a little', 'floating', + 'a bit', 'reviewing'] sep_words = ['and', ';', '+', '/', 'with special by'] nicknames = match.group(1) for word in ignore_words: @@ -119,7 +125,7 @@ ## print '%5d %s' % (n, name) ## else: ## print name - + items = authors_count.items() items.sort(key=operator.itemgetter(1), reverse=True) for name, n in items: 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 @@ -5,6 +5,11 @@ .. this is a revision shortly after release-2.1-beta .. startrev: 4eb52818e7c0 +.. branch: sanitise_bytecode_dispatch +Make PyPy's bytecode dispatcher easy to read, and less reliant on RPython +magic. There is no functional change, though the removal of dead code leads +to many fewer tests to execute. + .. branch: fastjson Fast json decoder written in RPython, about 3-4x faster than the pure Python decoder which comes with the stdlib @@ -75,3 +80,17 @@ .. branch: reflex-support .. branch: numpypy-inplace-op .. branch: rewritten-loop-logging + +.. branch: nobold-backtrace +Work on improving UnionError messages and stack trace displays. + +.. branch: improve-errors-again +More improvements and refactorings of error messages. + +.. branch: improve-errors-again2 +Unbreak tests in rlib. + +.. branch: less-stringly-ops +Use subclasses of SpaceOperation instead of SpaceOperator objects. +Random cleanups in flowspace. + 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 @@ -982,9 +982,8 @@ return self._call_has_no_star_args(call) and not call.keywords def _optimize_method_call(self, call): - if not self.space.config.objspace.opcodes.CALL_METHOD or \ - not self._call_has_no_star_args(call) or \ - not isinstance(call.func, ast.Attribute): + if not self._call_has_no_star_args(call) or \ + not isinstance(call.func, ast.Attribute): return False attr_lookup = call.func assert isinstance(attr_lookup, ast.Attribute) diff --git a/pypy/interpreter/pycode.py b/pypy/interpreter/pycode.py --- a/pypy/interpreter/pycode.py +++ b/pypy/interpreter/pycode.py @@ -251,8 +251,10 @@ tuple(self.co_cellvars)) def exec_host_bytecode(self, w_globals, w_locals): - from pypy.interpreter.pyframe import CPythonFrame - frame = CPythonFrame(self.space, self, w_globals, None) + if sys.version_info < (2, 7): + raise Exception("PyPy no longer supports Python 2.6 or lower") + from pypy.interpreter.pyframe import PyFrame + frame = self.space.FrameClass(self.space, self, w_globals, None) frame.setdictscope(w_locals) return frame.run() diff --git a/pypy/interpreter/pyframe.py b/pypy/interpreter/pyframe.py --- a/pypy/interpreter/pyframe.py +++ b/pypy/interpreter/pyframe.py @@ -52,7 +52,7 @@ def __init__(self, space, code, w_globals, outer_func): if not we_are_translated(): - assert type(self) in (space.FrameClass, CPythonFrame), ( + assert type(self) == space.FrameClass, ( "use space.FrameClass(), not directly PyFrame()") self = hint(self, access_directly=True, fresh_virtualizable=True) assert isinstance(code, pycode.PyCode) @@ -674,17 +674,6 @@ return space.wrap(self.builtin is not space.builtin) return space.w_False -class CPythonFrame(PyFrame): - """ - Execution of host (CPython) opcodes. - """ - - bytecode_spec = host_bytecode_spec - opcode_method_names = host_bytecode_spec.method_names - opcodedesc = host_bytecode_spec.opcodedesc - opdescmap = host_bytecode_spec.opdescmap - HAVE_ARGUMENT = host_bytecode_spec.HAVE_ARGUMENT - # ____________________________________________________________ diff --git a/pypy/interpreter/pyopcode.py b/pypy/interpreter/pyopcode.py --- a/pypy/interpreter/pyopcode.py +++ b/pypy/interpreter/pyopcode.py @@ -13,10 +13,8 @@ from rpython.rlib.objectmodel import we_are_translated from rpython.rlib import jit, rstackovf from rpython.rlib.rarithmetic import r_uint, intmask -from rpython.rlib.unroll import unrolling_iterable from rpython.rlib.debug import check_nonneg -from pypy.tool.stdlib_opcode import (bytecode_spec, - unrolling_all_opcode_descs) +from pypy.tool.stdlib_opcode import bytecode_spec def unaryoperation(operationname): """NOT_RPYTHON""" @@ -41,34 +39,14 @@ return func_with_new_name(opimpl, "opcode_impl_for_%s" % operationname) -compare_dispatch_table = [ - "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_dispatch_table)) - +opcodedesc = bytecode_spec.opcodedesc +HAVE_ARGUMENT = bytecode_spec.HAVE_ARGUMENT class __extend__(pyframe.PyFrame): """A PyFrame that knows about interpretation of standard Python opcodes minus the ones related to nested scopes.""" - bytecode_spec = bytecode_spec - opcode_method_names = bytecode_spec.method_names - opcodedesc = bytecode_spec.opcodedesc - opdescmap = bytecode_spec.opdescmap - HAVE_ARGUMENT = bytecode_spec.HAVE_ARGUMENT - ### opcode dispatch ### def dispatch(self, pycode, next_instr, ec): @@ -170,7 +148,7 @@ opcode = ord(co_code[next_instr]) next_instr += 1 - if opcode >= self.HAVE_ARGUMENT: + if opcode >= HAVE_ARGUMENT: lo = ord(co_code[next_instr]) hi = ord(co_code[next_instr+1]) next_instr += 2 @@ -180,19 +158,18 @@ # note: the structure of the code here is such that it makes # (after translation) a big "if/elif" chain, which is then - # turned into a switch(). It starts here: even if the first - # one is not an "if" but a "while" the effect is the same. + # turned into a switch(). - while opcode == self.opcodedesc.EXTENDED_ARG.index: + while opcode == opcodedesc.EXTENDED_ARG.index: opcode = ord(co_code[next_instr]) - if opcode < self.HAVE_ARGUMENT: + if opcode < HAVE_ARGUMENT: raise BytecodeCorruption lo = ord(co_code[next_instr+1]) hi = ord(co_code[next_instr+2]) next_instr += 3 oparg = (oparg * 65536) | (hi * 256) | lo - if opcode == self.opcodedesc.RETURN_VALUE.index: + if opcode == opcodedesc.RETURN_VALUE.index: w_returnvalue = self.popvalue() block = self.unrollstack(SReturnValue.kind) if block is None: @@ -202,8 +179,7 @@ unroller = SReturnValue(w_returnvalue) next_instr = block.handle(self, unroller) return next_instr # now inside a 'finally' block - - if opcode == self.opcodedesc.END_FINALLY.index: + elif opcode == opcodedesc.END_FINALLY.index: unroller = self.end_finally() if isinstance(unroller, SuspendedUnroller): # go on unrolling the stack @@ -215,49 +191,248 @@ else: next_instr = block.handle(self, unroller) return next_instr - - if opcode == self.opcodedesc.JUMP_ABSOLUTE.index: + elif opcode == opcodedesc.JUMP_ABSOLUTE.index: return self.jump_absolute(oparg, ec) - - if we_are_translated(): - for opdesc in unrolling_all_opcode_descs: - # static checks to skip this whole case if necessary - if opdesc.bytecode_spec is not self.bytecode_spec: - continue - if not opdesc.is_enabled(space): - continue - if opdesc.methodname in ( - 'EXTENDED_ARG', 'RETURN_VALUE', - 'END_FINALLY', 'JUMP_ABSOLUTE'): - continue # opcodes implemented above - - # the following "if" is part of the big switch described - # above. - if opcode == opdesc.index: - # dispatch to the opcode method - meth = getattr(self, opdesc.methodname) - res = meth(oparg, next_instr) - # !! warning, for the annotator the next line is not - # comparing an int and None - you can't do that. - # Instead, it's constant-folded to either True or False - if res is not None: - next_instr = res - break - else: - self.MISSING_OPCODE(oparg, next_instr) - - else: # when we are not translated, a list lookup is much faster - methodname = self.opcode_method_names[opcode] - try: - meth = getattr(self, methodname) - except AttributeError: - raise BytecodeCorruption("unimplemented opcode, ofs=%d, " - "code=%d, name=%s" % - (self.last_instr, opcode, - methodname)) - res = meth(oparg, next_instr) - if res is not None: - next_instr = res + elif opcode == opcodedesc.BREAK_LOOP.index: + next_instr = self.BREAK_LOOP(oparg, next_instr) + elif opcode == opcodedesc.CONTINUE_LOOP.index: + next_instr = self.CONTINUE_LOOP(oparg, next_instr) + elif opcode == opcodedesc.FOR_ITER.index: + next_instr = self.FOR_ITER(oparg, next_instr) + elif opcode == opcodedesc.JUMP_FORWARD.index: + next_instr = self.JUMP_FORWARD(oparg, next_instr) + elif opcode == opcodedesc.JUMP_IF_FALSE_OR_POP.index: + next_instr = self.JUMP_IF_FALSE_OR_POP(oparg, next_instr) + elif opcode == opcodedesc.JUMP_IF_NOT_DEBUG.index: + next_instr = self.JUMP_IF_NOT_DEBUG(oparg, next_instr) + elif opcode == opcodedesc.JUMP_IF_TRUE_OR_POP.index: + next_instr = self.JUMP_IF_TRUE_OR_POP(oparg, next_instr) + elif opcode == opcodedesc.POP_JUMP_IF_FALSE.index: + next_instr = self.POP_JUMP_IF_FALSE(oparg, next_instr) + elif opcode == opcodedesc.POP_JUMP_IF_TRUE.index: + next_instr = self.POP_JUMP_IF_TRUE(oparg, next_instr) + elif opcode == opcodedesc.BINARY_ADD.index: + self.BINARY_ADD(oparg, next_instr) + elif opcode == opcodedesc.BINARY_AND.index: + self.BINARY_AND(oparg, next_instr) + elif opcode == opcodedesc.BINARY_DIVIDE.index: + self.BINARY_DIVIDE(oparg, next_instr) + elif opcode == opcodedesc.BINARY_FLOOR_DIVIDE.index: + self.BINARY_FLOOR_DIVIDE(oparg, next_instr) + elif opcode == opcodedesc.BINARY_LSHIFT.index: + self.BINARY_LSHIFT(oparg, next_instr) + elif opcode == opcodedesc.BINARY_MODULO.index: + self.BINARY_MODULO(oparg, next_instr) + elif opcode == opcodedesc.BINARY_MULTIPLY.index: + self.BINARY_MULTIPLY(oparg, next_instr) + elif opcode == opcodedesc.BINARY_OR.index: + self.BINARY_OR(oparg, next_instr) + elif opcode == opcodedesc.BINARY_POWER.index: + self.BINARY_POWER(oparg, next_instr) + elif opcode == opcodedesc.BINARY_RSHIFT.index: + self.BINARY_RSHIFT(oparg, next_instr) + elif opcode == opcodedesc.BINARY_SUBSCR.index: + self.BINARY_SUBSCR(oparg, next_instr) + elif opcode == opcodedesc.BINARY_SUBTRACT.index: + self.BINARY_SUBTRACT(oparg, next_instr) + elif opcode == opcodedesc.BINARY_TRUE_DIVIDE.index: + self.BINARY_TRUE_DIVIDE(oparg, next_instr) + elif opcode == opcodedesc.BINARY_XOR.index: + self.BINARY_XOR(oparg, next_instr) + elif opcode == opcodedesc.BUILD_CLASS.index: + self.BUILD_CLASS(oparg, next_instr) + elif opcode == opcodedesc.BUILD_LIST.index: + self.BUILD_LIST(oparg, next_instr) + elif opcode == opcodedesc.BUILD_LIST_FROM_ARG.index: + self.BUILD_LIST_FROM_ARG(oparg, next_instr) + elif opcode == opcodedesc.BUILD_MAP.index: + self.BUILD_MAP(oparg, next_instr) + elif opcode == opcodedesc.BUILD_SET.index: + self.BUILD_SET(oparg, next_instr) + elif opcode == opcodedesc.BUILD_SLICE.index: + self.BUILD_SLICE(oparg, next_instr) + elif opcode == opcodedesc.BUILD_TUPLE.index: + self.BUILD_TUPLE(oparg, next_instr) + elif opcode == opcodedesc.CALL_FUNCTION.index: + self.CALL_FUNCTION(oparg, next_instr) + elif opcode == opcodedesc.CALL_FUNCTION_KW.index: + self.CALL_FUNCTION_KW(oparg, next_instr) + elif opcode == opcodedesc.CALL_FUNCTION_VAR.index: + self.CALL_FUNCTION_VAR(oparg, next_instr) + elif opcode == opcodedesc.CALL_FUNCTION_VAR_KW.index: + self.CALL_FUNCTION_VAR_KW(oparg, next_instr) + elif opcode == opcodedesc.CALL_METHOD.index: + self.CALL_METHOD(oparg, next_instr) + elif opcode == opcodedesc.COMPARE_OP.index: + self.COMPARE_OP(oparg, next_instr) + elif opcode == opcodedesc.DELETE_ATTR.index: + self.DELETE_ATTR(oparg, next_instr) + elif opcode == opcodedesc.DELETE_FAST.index: + self.DELETE_FAST(oparg, next_instr) + elif opcode == opcodedesc.DELETE_GLOBAL.index: + self.DELETE_GLOBAL(oparg, next_instr) + elif opcode == opcodedesc.DELETE_NAME.index: + self.DELETE_NAME(oparg, next_instr) + elif opcode == opcodedesc.DELETE_SLICE_0.index: + self.DELETE_SLICE_0(oparg, next_instr) + elif opcode == opcodedesc.DELETE_SLICE_1.index: + self.DELETE_SLICE_1(oparg, next_instr) + elif opcode == opcodedesc.DELETE_SLICE_2.index: + self.DELETE_SLICE_2(oparg, next_instr) + elif opcode == opcodedesc.DELETE_SLICE_3.index: + self.DELETE_SLICE_3(oparg, next_instr) + elif opcode == opcodedesc.DELETE_SUBSCR.index: + self.DELETE_SUBSCR(oparg, next_instr) + elif opcode == opcodedesc.DUP_TOP.index: + self.DUP_TOP(oparg, next_instr) + elif opcode == opcodedesc.DUP_TOPX.index: + self.DUP_TOPX(oparg, next_instr) + elif opcode == opcodedesc.EXEC_STMT.index: + self.EXEC_STMT(oparg, next_instr) + elif opcode == opcodedesc.GET_ITER.index: + self.GET_ITER(oparg, next_instr) + elif opcode == opcodedesc.IMPORT_FROM.index: + self.IMPORT_FROM(oparg, next_instr) + elif opcode == opcodedesc.IMPORT_NAME.index: + self.IMPORT_NAME(oparg, next_instr) + elif opcode == opcodedesc.IMPORT_STAR.index: + self.IMPORT_STAR(oparg, next_instr) + elif opcode == opcodedesc.INPLACE_ADD.index: + self.INPLACE_ADD(oparg, next_instr) + elif opcode == opcodedesc.INPLACE_AND.index: + self.INPLACE_AND(oparg, next_instr) + elif opcode == opcodedesc.INPLACE_DIVIDE.index: + self.INPLACE_DIVIDE(oparg, next_instr) + elif opcode == opcodedesc.INPLACE_FLOOR_DIVIDE.index: + self.INPLACE_FLOOR_DIVIDE(oparg, next_instr) + elif opcode == opcodedesc.INPLACE_LSHIFT.index: + self.INPLACE_LSHIFT(oparg, next_instr) + elif opcode == opcodedesc.INPLACE_MODULO.index: + self.INPLACE_MODULO(oparg, next_instr) + elif opcode == opcodedesc.INPLACE_MULTIPLY.index: + self.INPLACE_MULTIPLY(oparg, next_instr) + elif opcode == opcodedesc.INPLACE_OR.index: + self.INPLACE_OR(oparg, next_instr) + elif opcode == opcodedesc.INPLACE_POWER.index: + self.INPLACE_POWER(oparg, next_instr) + elif opcode == opcodedesc.INPLACE_RSHIFT.index: + self.INPLACE_RSHIFT(oparg, next_instr) + elif opcode == opcodedesc.INPLACE_SUBTRACT.index: + self.INPLACE_SUBTRACT(oparg, next_instr) + elif opcode == opcodedesc.INPLACE_TRUE_DIVIDE.index: + self.INPLACE_TRUE_DIVIDE(oparg, next_instr) + elif opcode == opcodedesc.INPLACE_XOR.index: + self.INPLACE_XOR(oparg, next_instr) + elif opcode == opcodedesc.LIST_APPEND.index: + self.LIST_APPEND(oparg, next_instr) + elif opcode == opcodedesc.LOAD_ATTR.index: + self.LOAD_ATTR(oparg, next_instr) + elif opcode == opcodedesc.LOAD_CLOSURE.index: + self.LOAD_CLOSURE(oparg, next_instr) + elif opcode == opcodedesc.LOAD_CONST.index: + self.LOAD_CONST(oparg, next_instr) + elif opcode == opcodedesc.LOAD_DEREF.index: + self.LOAD_DEREF(oparg, next_instr) + elif opcode == opcodedesc.LOAD_FAST.index: + self.LOAD_FAST(oparg, next_instr) + elif opcode == opcodedesc.LOAD_GLOBAL.index: + self.LOAD_GLOBAL(oparg, next_instr) + elif opcode == opcodedesc.LOAD_LOCALS.index: + self.LOAD_LOCALS(oparg, next_instr) + elif opcode == opcodedesc.LOAD_NAME.index: + self.LOAD_NAME(oparg, next_instr) + elif opcode == opcodedesc.LOOKUP_METHOD.index: + self.LOOKUP_METHOD(oparg, next_instr) + elif opcode == opcodedesc.MAKE_CLOSURE.index: + self.MAKE_CLOSURE(oparg, next_instr) + elif opcode == opcodedesc.MAKE_FUNCTION.index: + self.MAKE_FUNCTION(oparg, next_instr) + elif opcode == opcodedesc.MAP_ADD.index: + self.MAP_ADD(oparg, next_instr) + elif opcode == opcodedesc.NOP.index: + self.NOP(oparg, next_instr) + elif opcode == opcodedesc.POP_BLOCK.index: + self.POP_BLOCK(oparg, next_instr) + elif opcode == opcodedesc.POP_TOP.index: + self.POP_TOP(oparg, next_instr) + elif opcode == opcodedesc.PRINT_EXPR.index: + self.PRINT_EXPR(oparg, next_instr) + elif opcode == opcodedesc.PRINT_ITEM.index: + self.PRINT_ITEM(oparg, next_instr) + elif opcode == opcodedesc.PRINT_ITEM_TO.index: + self.PRINT_ITEM_TO(oparg, next_instr) + elif opcode == opcodedesc.PRINT_NEWLINE.index: + self.PRINT_NEWLINE(oparg, next_instr) + elif opcode == opcodedesc.PRINT_NEWLINE_TO.index: + self.PRINT_NEWLINE_TO(oparg, next_instr) + elif opcode == opcodedesc.RAISE_VARARGS.index: + self.RAISE_VARARGS(oparg, next_instr) + elif opcode == opcodedesc.ROT_FOUR.index: + self.ROT_FOUR(oparg, next_instr) + elif opcode == opcodedesc.ROT_THREE.index: + self.ROT_THREE(oparg, next_instr) + elif opcode == opcodedesc.ROT_TWO.index: + self.ROT_TWO(oparg, next_instr) + elif opcode == opcodedesc.SETUP_EXCEPT.index: + self.SETUP_EXCEPT(oparg, next_instr) + elif opcode == opcodedesc.SETUP_FINALLY.index: + self.SETUP_FINALLY(oparg, next_instr) + elif opcode == opcodedesc.SETUP_LOOP.index: + self.SETUP_LOOP(oparg, next_instr) + elif opcode == opcodedesc.SETUP_WITH.index: + self.SETUP_WITH(oparg, next_instr) + elif opcode == opcodedesc.SET_ADD.index: + self.SET_ADD(oparg, next_instr) + elif opcode == opcodedesc.SLICE_0.index: + self.SLICE_0(oparg, next_instr) + elif opcode == opcodedesc.SLICE_1.index: + self.SLICE_1(oparg, next_instr) + elif opcode == opcodedesc.SLICE_2.index: + self.SLICE_2(oparg, next_instr) + elif opcode == opcodedesc.SLICE_3.index: + self.SLICE_3(oparg, next_instr) + elif opcode == opcodedesc.STOP_CODE.index: + self.STOP_CODE(oparg, next_instr) + elif opcode == opcodedesc.STORE_ATTR.index: + self.STORE_ATTR(oparg, next_instr) + elif opcode == opcodedesc.STORE_DEREF.index: + self.STORE_DEREF(oparg, next_instr) + elif opcode == opcodedesc.STORE_FAST.index: + self.STORE_FAST(oparg, next_instr) + elif opcode == opcodedesc.STORE_GLOBAL.index: + self.STORE_GLOBAL(oparg, next_instr) + elif opcode == opcodedesc.STORE_MAP.index: + self.STORE_MAP(oparg, next_instr) + elif opcode == opcodedesc.STORE_NAME.index: + self.STORE_NAME(oparg, next_instr) + elif opcode == opcodedesc.STORE_SLICE_0.index: + self.STORE_SLICE_0(oparg, next_instr) + elif opcode == opcodedesc.STORE_SLICE_1.index: + self.STORE_SLICE_1(oparg, next_instr) + elif opcode == opcodedesc.STORE_SLICE_2.index: + self.STORE_SLICE_2(oparg, next_instr) + elif opcode == opcodedesc.STORE_SLICE_3.index: + self.STORE_SLICE_3(oparg, next_instr) + elif opcode == opcodedesc.STORE_SUBSCR.index: + self.STORE_SUBSCR(oparg, next_instr) + elif opcode == opcodedesc.UNARY_CONVERT.index: + self.UNARY_CONVERT(oparg, next_instr) + elif opcode == opcodedesc.UNARY_INVERT.index: + self.UNARY_INVERT(oparg, next_instr) + elif opcode == opcodedesc.UNARY_NEGATIVE.index: + self.UNARY_NEGATIVE(oparg, next_instr) + elif opcode == opcodedesc.UNARY_NOT.index: + self.UNARY_NOT(oparg, next_instr) + elif opcode == opcodedesc.UNARY_POSITIVE.index: + self.UNARY_POSITIVE(oparg, next_instr) + elif opcode == opcodedesc.UNPACK_SEQUENCE.index: + self.UNPACK_SEQUENCE(oparg, next_instr) + elif opcode == opcodedesc.WITH_CLEANUP.index: + self.WITH_CLEANUP(oparg, next_instr) + elif opcode == opcodedesc.YIELD_VALUE.index: + self.YIELD_VALUE(oparg, next_instr) + else: + self.MISSING_OPCODE(oparg, next_instr) if jit.we_are_jitted(): return next_instr @@ -733,36 +908,6 @@ self.pushvalue(w_value) LOAD_ATTR._always_inline_ = True - def cmp_lt(self, w_1, w_2): - return self.space.lt(w_1, w_2) - - def cmp_le(self, w_1, w_2): - return self.space.le(w_1, w_2) - - def cmp_eq(self, w_1, w_2): - return self.space.eq(w_1, w_2) - - def cmp_ne(self, w_1, w_2): - return self.space.ne(w_1, w_2) - - def cmp_gt(self, w_1, w_2): - return self.space.gt(w_1, w_2) - - def cmp_ge(self, w_1, w_2): - return self.space.ge(w_1, w_2) - - def cmp_in(self, w_1, w_2): - return self.space.contains(w_2, w_1) - - def cmp_not_in(self, w_1, w_2): - return self.space.not_(self.space.contains(w_2, w_1)) - - def cmp_is(self, w_1, w_2): - return self.space.is_(w_1, w_2) - - def cmp_is_not(self, w_1, w_2): - return self.space.not_(self.space.is_(w_1, w_2)) - @jit.unroll_safe def cmp_exc_match(self, w_1, w_2): space = self.space @@ -779,11 +924,28 @@ def COMPARE_OP(self, testnum, next_instr): w_2 = self.popvalue() w_1 = self.popvalue() - w_result = None - for i, attr in unrolling_compare_dispatch_table: - if i == testnum: - w_result = getattr(self, attr)(w_1, w_2) - break + if testnum == 0: + w_result = self.space.lt(w_1, w_2) + elif testnum == 1: + w_result = self.space.le(w_1, w_2) + elif testnum == 2: + w_result = self.space.eq(w_1, w_2) + elif testnum == 3: + w_result = self.space.ne(w_1, w_2) + elif testnum == 4: + w_result = self.space.gt(w_1, w_2) + elif testnum == 5: + w_result = self.space.ge(w_1, w_2) + elif testnum == 6: + w_result = self.space.contains(w_2, w_1) + elif testnum == 7: + w_result = self.space.not_(self.space.contains(w_2, w_1)) + elif testnum == 8: + w_result = self.space.is_(w_1, w_2) + elif testnum == 9: + w_result = self.space.not_(self.space.is_(w_1, w_2)) + elif testnum == 10: + w_result = self.cmp_exc_match(w_1, w_2) else: raise BytecodeCorruption("bad COMPARE_OP oparg") self.pushvalue(w_result) @@ -1086,49 +1248,6 @@ self.space.setitem(w_dict, w_key, w_value) -class __extend__(pyframe.CPythonFrame): - - def JUMP_IF_FALSE(self, stepby, next_instr): - w_cond = self.peekvalue() - if not self.space.is_true(w_cond): - next_instr += stepby - return next_instr - - def JUMP_IF_TRUE(self, stepby, next_instr): - w_cond = self.peekvalue() - if self.space.is_true(w_cond): - next_instr += stepby - return next_instr - - def BUILD_MAP(self, itemcount, next_instr): - if sys.version_info >= (2, 6): - # We could pre-allocate a dict here - # but for the moment this code is not translated. - pass - else: - if itemcount != 0: - raise BytecodeCorruption - w_dict = self.space.newdict() - self.pushvalue(w_dict) - - def STORE_MAP(self, zero, next_instr): - if sys.version_info >= (2, 6): - w_key = self.popvalue() - w_value = self.popvalue() - w_dict = self.peekvalue() - self.space.setitem(w_dict, w_key, w_value) - else: - raise BytecodeCorruption - - def LIST_APPEND(self, oparg, next_instr): - w = self.popvalue() - if sys.version_info < (2, 7): - v = self.popvalue() - else: - v = self.peekvalue(oparg - 1) - self.space.call_method(v, 'append', w) - - ### ____________________________________________________________ ### class ExitFrame(Exception): 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 @@ -953,10 +953,6 @@ assert i > -1 assert isinstance(co.co_consts[i], frozenset) - -class AppTestCallMethod(object): - spaceconfig = {'objspace.opcodes.CALL_METHOD': True} - def test_call_method_kwargs(self): source = """def _f(a): return a.f(a=a) diff --git a/pypy/interpreter/test/test_executioncontext.py b/pypy/interpreter/test/test_executioncontext.py --- a/pypy/interpreter/test/test_executioncontext.py +++ b/pypy/interpreter/test/test_executioncontext.py @@ -253,10 +253,6 @@ """) -class TestExecutionContextWithCallMethod(TestExecutionContext): - spaceconfig ={'objspace.opcodes.CALL_METHOD': True} - - class AppTestDelNotBlocked: def setup_method(self, meth): 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 @@ -812,10 +812,6 @@ assert len(called) == 1 assert isinstance(called[0], argument.Arguments) -class TestPassThroughArguments_CALL_METHOD(TestPassThroughArguments): - spaceconfig = dict(usemodules=('itertools',), **{ - "objspace.opcodes.CALL_METHOD": True - }) class AppTestKeywordsToBuiltinSanity(object): 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 @@ -1516,13 +1516,18 @@ d = BStruct.fields assert d[0][1].offset == d[1][1].offset == d[2][1].offset == 0 assert d[3][1].offset == sizeof(BLong) - assert d[0][1].bitshift == 0 + def f(m, r): + if sys.byteorder == 'little': + return r + else: + return LONGBITS - m - r + assert d[0][1].bitshift == f(1, 0) assert d[0][1].bitsize == 1 - assert d[1][1].bitshift == 1 + assert d[1][1].bitshift == f(2, 1) assert d[1][1].bitsize == 2 - assert d[2][1].bitshift == 3 + assert d[2][1].bitshift == f(3, 3) assert d[2][1].bitsize == 3 - assert d[3][1].bitshift == 0 + assert d[3][1].bitshift == f(LONGBITS - 5, 0) assert d[3][1].bitsize == LONGBITS - 5 assert sizeof(BStruct) == 2 * sizeof(BLong) assert alignof(BStruct) == alignof(BLong) @@ -2856,7 +2861,7 @@ ('b1', BInt, 9), ('b2', BUInt, 7), ('c', BChar, -1)], -1, -1, -1, flag) - if flag % 2 == 0: # gcc and gcc ARM + if flag % 2 == 0: # gcc, any variant assert typeoffsetof(BStruct, 'c') == (BChar, 3) assert sizeof(BStruct) == 4 else: # msvc @@ -2864,6 +2869,31 @@ assert sizeof(BStruct) == 12 assert alignof(BStruct) == 4 # + p = newp(new_pointer_type(BStruct), None) + p.a = b'A' + p.b1 = -201 + p.b2 = 99 + p.c = b'\x9D' + raw = buffer(p)[:] + if sys.byteorder == 'little': + if flag == 0 or flag == 2: # gcc, little endian + assert raw == b'A7\xC7\x9D' + elif flag == 1: # msvc + assert raw == b'A\x00\x00\x007\xC7\x00\x00\x9D\x00\x00\x00' + elif flag == 4: # gcc, big endian + assert raw == b'A\xE3\x9B\x9D' + else: + raise AssertionError("bad flag") + else: + if flag == 0 or flag == 2: # gcc + assert raw == b'A\xC77\x9D' + elif flag == 1: # msvc + assert raw == b'A\x00\x00\x00\x00\x00\xC77\x9D\x00\x00\x00' + elif flag == 4: # gcc, big endian + assert raw == b'A\x9B\xE3\x9D' + else: + raise AssertionError("bad flag") + # BStruct = new_struct_type("struct foo2") complete_struct_or_union(BStruct, [('a', BChar, -1), ('', BShort, 9), @@ -2875,16 +2905,21 @@ elif flag == 1: # msvc assert sizeof(BStruct) == 6 assert alignof(BStruct) == 2 - else: # gcc ARM + elif flag == 2: # gcc ARM assert sizeof(BStruct) == 6 assert alignof(BStruct) == 2 + elif flag == 4: # gcc, big endian + assert sizeof(BStruct) == 5 + assert alignof(BStruct) == 1 + else: + raise AssertionError("bad flag") # BStruct = new_struct_type("struct foo2") complete_struct_or_union(BStruct, [('a', BChar, -1), ('', BInt, 0), ('', BInt, 0), ('c', BChar, -1)], -1, -1, -1, flag) - if flag == 0: # gcc + if flag == 0: # gcc assert typeoffsetof(BStruct, 'c') == (BChar, 4) assert sizeof(BStruct) == 5 assert alignof(BStruct) == 1 @@ -2892,10 +2927,16 @@ assert typeoffsetof(BStruct, 'c') == (BChar, 1) assert sizeof(BStruct) == 2 assert alignof(BStruct) == 1 - else: # gcc ARM + elif flag == 2: # gcc ARM assert typeoffsetof(BStruct, 'c') == (BChar, 4) assert sizeof(BStruct) == 8 assert alignof(BStruct) == 4 + elif flag == 4: # gcc, big endian + assert typeoffsetof(BStruct, 'c') == (BChar, 4) + assert sizeof(BStruct) == 5 + assert alignof(BStruct) == 1 + else: + raise AssertionError("bad flag") def test_bitfield_as_gcc(): @@ -2907,6 +2948,11 @@ def test_bitfield_as_arm_gcc(): _test_bitfield_details(flag=2) +def test_bitfield_as_big_endian(): + if '__pypy__' in sys.builtin_module_names: + py.test.skip("no big endian machine supported on pypy for now") + _test_bitfield_details(flag=4) + def test_version(): # this test is here mostly for PyPy diff --git a/pypy/module/_continuation/interp_pickle.py b/pypy/module/_continuation/interp_pickle.py --- a/pypy/module/_continuation/interp_pickle.py +++ b/pypy/module/_continuation/interp_pickle.py @@ -120,8 +120,7 @@ nkwds = (oparg >> 8) & 0xff if nkwds == 0: # only positional arguments # fast paths leaves things on the stack, pop them - if (frame.space.config.objspace.opcodes.CALL_METHOD and - opcode == map['CALL_METHOD']): + if opcode == map['CALL_METHOD']: frame.dropvalues(nargs + 2) elif opcode == map['CALL_FUNCTION']: frame.dropvalues(nargs + 1) diff --git a/pypy/module/_continuation/test/test_zpickle.py b/pypy/module/_continuation/test/test_zpickle.py --- a/pypy/module/_continuation/test/test_zpickle.py +++ b/pypy/module/_continuation/test/test_zpickle.py @@ -1,8 +1,7 @@ class AppTestCopy: spaceconfig = dict(usemodules=['_continuation'], - continuation=True, - CALL_METHOD=True) + continuation=True) def test_basic_setup(self): from _continuation import continulet @@ -104,7 +103,6 @@ spaceconfig = { "usemodules": ['_continuation', 'struct', 'binascii'], "continuation": True, - "CALL_METHOD": True, } def setup_class(cls): diff --git a/pypy/module/_lsprof/test/test_cprofile.py b/pypy/module/_lsprof/test/test_cprofile.py --- a/pypy/module/_lsprof/test/test_cprofile.py +++ b/pypy/module/_lsprof/test/test_cprofile.py @@ -191,11 +191,6 @@ sys.path.pop(0) -class AppTestWithDifferentBytecodes(AppTestCProfile): - spaceconfig = AppTestCProfile.spaceconfig.copy() - spaceconfig['objspace.opcodes.CALL_METHOD'] = True - - expected_output = {} expected_output['print_stats'] = """\ 126 function calls (106 primitive calls) in 1.000 seconds 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 @@ -841,8 +841,7 @@ # # default_magic - 6 -- used by CPython without the -U option # default_magic - 5 -- used by CPython with the -U option -# default_magic -- used by PyPy without the CALL_METHOD opcode -# default_magic + 2 -- used by PyPy with the CALL_METHOD opcode +# default_magic -- used by PyPy [because of CALL_METHOD] # from pypy.interpreter.pycode import default_magic MARSHAL_VERSION_FOR_PYC = 2 @@ -855,10 +854,7 @@ magic = __import__('imp').get_magic() return struct.unpack('" - "ge", # ">=" - ] -unrolling_compare_ops = unrolling_iterable(enumerate(compare_table)) - -def fast_COMPARE_OP(f, testnum, next_instr): - w_2 = f.popvalue() - w_1 = f.popvalue() - w_result = None - if (type(w_2) is intobject.W_IntObject and - type(w_1) is intobject.W_IntObject and - testnum < len(compare_table)): - for i, attr in unrolling_compare_ops: - if i == testnum: - op = getattr(operator, attr) - w_result = f.space.newbool(op(w_1.intval, - w_2.intval)) - break - else: - for i, attr in pyopcode.unrolling_compare_dispatch_table: - if i == testnum: - w_result = getattr(f, attr)(w_1, w_2) - break - else: - raise pyopcode.BytecodeCorruption, "bad COMPARE_OP oparg" - f.pushvalue(w_result) - def build_frame(space): """Consider the objspace config and return a patched frame object.""" @@ -91,10 +59,7 @@ 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: - from pypy.objspace.std.callmethod import LOOKUP_METHOD, CALL_METHOD - StdObjSpaceFrame.LOOKUP_METHOD = LOOKUP_METHOD - StdObjSpaceFrame.CALL_METHOD = CALL_METHOD - if space.config.objspace.std.optimized_comparison_op: - StdObjSpaceFrame.COMPARE_OP = fast_COMPARE_OP + from pypy.objspace.std.callmethod import LOOKUP_METHOD, CALL_METHOD + StdObjSpaceFrame.LOOKUP_METHOD = LOOKUP_METHOD + StdObjSpaceFrame.CALL_METHOD = CALL_METHOD return StdObjSpaceFrame 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 @@ -39,9 +39,6 @@ def _never_equal_to(self, w_lookup_type): return False - def w_keys(self, w_dict): - 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): if self.is_correct_type(w_key): self.setitem_str(w_dict, self.unwrap(w_key), w_value) @@ -57,7 +54,6 @@ jit.isconstant(self.length(w_dict)) and jit.isconstant(key)) def _setitem_str_indirection(self, w_dict, key, w_value): keys, values_w = self.unerase(w_dict.dstorage) - result = [] for i in range(len(keys)): if keys[i] == key: values_w[i] = w_value @@ -72,7 +68,6 @@ values_w.append(w_value) def setdefault(self, w_dict, 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) @@ -99,7 +94,6 @@ 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 = [] for i in range(len(keys)): if keys[i] == key: return values_w[i] @@ -164,14 +158,18 @@ def getiterkeys(self, w_dict): return iter(self.unerase(w_dict.dstorage)[0]) + def getitervalues(self, w_dict): return iter(self.unerase(w_dict.dstorage)[1]) + def getiteritems(self, w_dict): keys = self.unerase(w_dict.dstorage)[0] return iter(range(len(keys))) + def wrapkey(space, key): return space.wrap(key) + def next_item(self): strategy = self.strategy assert isinstance(strategy, KwargsDictStrategy) 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 @@ -591,10 +591,7 @@ return ObjSpace.getindex_w(self, w_obj, w_exception, objdescr) def call_method(self, w_obj, methname, *arg_w): - if self.config.objspace.opcodes.CALL_METHOD: - return callmethod.call_method_opt(self, w_obj, methname, *arg_w) - else: - return ObjSpace.call_method(self, w_obj, methname, *arg_w) + return callmethod.call_method_opt(self, w_obj, methname, *arg_w) def _type_issubtype(self, w_sub, w_type): if isinstance(w_sub, W_TypeObject) and isinstance(w_type, W_TypeObject): 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 @@ -230,13 +230,13 @@ return space.wrap(builder.build()) -def str_title__String(space, w_self): - input = w_self._value - builder = StringBuilder(len(input)) + + at jit.elidable +def title(s): + builder = StringBuilder(len(s)) prev_letter = ' ' - for pos in range(len(input)): - ch = input[pos] + for ch in s: if not prev_letter.isalpha(): ch = _upper(ch) builder.append(ch) @@ -245,39 +245,17 @@ builder.append(ch) prev_letter = ch + return builder.build() - return space.wrap(builder.build()) + +def str_title__String(space, w_self): + return space.wrap(title(w_self._value)) + def str_split__String_None_ANY(space, w_self, w_none, w_maxsplit=-1): maxsplit = space.int_w(w_maxsplit) - res = [] value = w_self._value - length = len(value) - i = 0 - while True: - # find the beginning of the next word - while i < length: - if not value[i].isspace(): - break # found - i += 1 - else: - break # end of string, finished - - # find the end of the word - if maxsplit == 0: - j = length # take all the rest of the string - else: - j = i + 1 - while j < length and not value[j].isspace(): - j += 1 - maxsplit -= 1 # NB. if it's already < 0, it stays < 0 - - # the word is value[i:j] - res.append(value[i:j]) - - # continue to look from the character following the space after the word - i = j + 1 - + res = split(value, maxsplit=maxsplit) return space.newlist_str(res) def str_split__String_String_ANY(space, w_self, w_by, w_maxsplit=-1): @@ -292,37 +270,8 @@ def str_rsplit__String_None_ANY(space, w_self, w_none, w_maxsplit=-1): maxsplit = space.int_w(w_maxsplit) - res = [] value = w_self._value - i = len(value)-1 - while True: - # starting from the end, find the end of the next word - while i >= 0: - if not value[i].isspace(): - break # found - i -= 1 - else: - break # end of string, finished - - # find the start of the word - # (more precisely, 'j' will be the space character before the word) - if maxsplit == 0: - j = -1 # take all the rest of the string - else: - j = i - 1 - while j >= 0 and not value[j].isspace(): - j -= 1 - maxsplit -= 1 # NB. if it's already < 0, it stays < 0 - - # the word is value[j+1:i+1] - j1 = j + 1 - assert j1 >= 0 - res.append(value[j1:i+1]) - - # continue to look from the character before the space before the word - i = j - 1 - - res.reverse() + res = rsplit(value, maxsplit=maxsplit) return space.newlist_str(res) def str_rsplit__String_String_ANY(space, w_self, w_by, w_maxsplit=-1): diff --git a/pypy/objspace/std/test/test_callmethod.py b/pypy/objspace/std/test/test_callmethod.py --- a/pypy/objspace/std/test/test_callmethod.py +++ b/pypy/objspace/std/test/test_callmethod.py @@ -2,8 +2,6 @@ # The exec hacking is needed to have the code snippets compiled # by our own compiler, not CPython's - spaceconfig = {"objspace.opcodes.CALL_METHOD": True} - def test_call_method(self): exec """if 1: class C(object): @@ -111,13 +109,10 @@ class AppTestCallMethodWithGetattributeShortcut(AppTestCallMethod): - spaceconfig = AppTestCallMethod.spaceconfig.copy() - spaceconfig["objspace.std.getattributeshortcut"] = True + spaceconfig = {"objspace.std.getattributeshortcut": True} class TestCallMethod: - spaceconfig = {"objspace.opcodes.CALL_METHOD": True} - def test_space_call_method(self): space = self.space w_lst = space.newlist([]) 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 @@ -501,6 +501,3 @@ class AppTestIntOptimizedAdd(AppTestInt): spaceconfig = {"objspace.std.optimized_int_add": True} - -class AppTestIntOptimizedComp(AppTestInt): - spaceconfig = {"objspace.std.optimized_comparison_op": True} diff --git a/pypy/objspace/std/test/test_mapdict.py b/pypy/objspace/std/test/test_mapdict.py --- a/pypy/objspace/std/test/test_mapdict.py +++ b/pypy/objspace/std/test/test_mapdict.py @@ -656,8 +656,7 @@ class AppTestWithMapDictAndCounters(object): spaceconfig = {"objspace.std.withmapdict": True, - "objspace.std.withmethodcachecounter": True, - "objspace.opcodes.CALL_METHOD": True} + "objspace.std.withmethodcachecounter": True} def setup_class(cls): from pypy.interpreter import gateway @@ -1001,8 +1000,7 @@ class AppTestGlobalCaching(AppTestWithMapDict): spaceconfig = {"objspace.std.withmethodcachecounter": True, - "objspace.std.withmapdict": True, - "objspace.opcodes.CALL_METHOD": True} + "objspace.std.withmapdict": True} def test_mix_classes(self): import __pypy__ diff --git a/pypy/tool/pytest/apptest.py b/pypy/tool/pytest/apptest.py --- a/pypy/tool/pytest/apptest.py +++ b/pypy/tool/pytest/apptest.py @@ -34,6 +34,8 @@ try: target(*args) except OperationError, e: + if self.config.option.verbose: + raise tb = sys.exc_info()[2] if e.match(space, space.w_KeyboardInterrupt): raise KeyboardInterrupt, KeyboardInterrupt(), tb diff --git a/rpython/annotator/binaryop.py b/rpython/annotator/binaryop.py --- a/rpython/annotator/binaryop.py +++ b/rpython/annotator/binaryop.py @@ -823,14 +823,14 @@ if pbc.isNone(): return %(classname)s(%(constructor_args)s) else: - return SomeObject() + raise UnionError(pbc, obj) class __extend__(pairtype(SomePBC, %(classname)s)): def union((pbc, obj)): if pbc.isNone(): return %(classname)s(%(constructor_args)s) else: - return SomeObject() + raise UnionError(pbc, obj) """ % loc) exec source.compile() in glob diff --git a/rpython/annotator/listdef.py b/rpython/annotator/listdef.py --- a/rpython/annotator/listdef.py +++ b/rpython/annotator/listdef.py @@ -1,12 +1,12 @@ from rpython.annotator.model import s_ImpossibleValue from rpython.annotator.model import SomeList, SomeString -from rpython.annotator.model import unionof, TLS, UnionError +from rpython.annotator.model import unionof, TLS, UnionError, AnnotatorError -class TooLateForChange(Exception): +class TooLateForChange(AnnotatorError): pass -class ListChangeUnallowed(Exception): +class ListChangeUnallowed(AnnotatorError): pass class ListItem(object): diff --git a/rpython/annotator/signature.py b/rpython/annotator/signature.py --- a/rpython/annotator/signature.py +++ b/rpython/annotator/signature.py @@ -5,7 +5,7 @@ from rpython.annotator.model import SomeBool, SomeInteger, SomeString,\ SomeFloat, SomeList, SomeDict, s_None, \ SomeObject, SomeInstance, SomeTuple, lltype_to_annotation,\ - unionof, SomeUnicodeString, SomeType + unionof, SomeUnicodeString, SomeType, AnnotatorError from rpython.annotator.listdef import ListDef from rpython.annotator.dictdef import DictDef @@ -118,25 +118,28 @@ else: args_s.append(annotation(argtype, bookkeeper=funcdesc.bookkeeper)) if len(inputcells) != len(args_s): - raise Exception("%r: expected %d args, got %d" % (funcdesc, + raise SignatureError("%r: expected %d args, got %d" % (funcdesc, len(args_s), len(inputcells))) for i, (s_arg, s_input) in enumerate(zip(args_s, inputcells)): s_input = unionof(s_input, s_arg) if not s_arg.contains(s_input): - raise Exception("%r argument %d:\n" + raise SignatureError("%r argument %d:\n" "expected %s,\n" " got %s" % (funcdesc, i+1, s_arg, s_input)) inputcells[:] = args_s +class SignatureError(AnnotatorError): + pass + def finish_type(paramtype, bookkeeper, func): 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,)) + raise SignatureError("%r argument declared as annotation.types.self(); class needs decorator rlib.signature.finishsigs()" % (func,)) elif isinstance(paramtype, AnyTypeMarker): return None else: @@ -149,7 +152,7 @@ if s_param is None: # can be anything continue if not s_param.contains(s_actual): - raise Exception("%r argument %d:\n" + raise SignatureError("%r argument %d:\n" "expected %s,\n" " got %s" % (funcdesc, i+1, s_param, s_actual)) for i, s_param in enumerate(params_s): @@ -160,7 +163,7 @@ def enforce_signature_return(funcdesc, sigtype, inferredtype): s_sigret = finish_type(sigtype, funcdesc.bookkeeper, funcdesc.pyobj) if s_sigret is not None and not s_sigret.contains(inferredtype): - raise Exception("%r return value:\n" + raise SignatureError("%r return value:\n" "expected %s,\n" " got %s" % (funcdesc, s_sigret, inferredtype)) return s_sigret diff --git a/rpython/annotator/specialize.py b/rpython/annotator/specialize.py --- a/rpython/annotator/specialize.py +++ b/rpython/annotator/specialize.py @@ -258,16 +258,17 @@ assert not s.can_be_None, "memo call: cannot mix None and PBCs" for desc in s.descriptions: if desc.pyobj is None: - raise Exception("memo call with a class or PBC that has no " - "corresponding Python object (%r)" % (desc,)) + raise annmodel.AnnotatorError( + "memo call with a class or PBC that has no " + "corresponding Python object (%r)" % (desc,)) values.append(desc.pyobj) elif isinstance(s, SomeImpossibleValue): return s # we will probably get more possible args later elif isinstance(s, SomeBool): values = [False, True] else: - raise Exception("memo call: argument must be a class or a frozen " - "PBC, got %r" % (s,)) + raise annmodel.AnnotatorError("memo call: argument must be a class" + "or a frozen PBC, got %r" % (s,)) argvalues.append(values) # the list of all possible tuples of arguments to give to the memo function possiblevalues = cartesian_product(argvalues) @@ -280,8 +281,8 @@ except KeyError: func = funcdesc.pyobj if func is None: - raise Exception("memo call: no Python function object to call " - "(%r)" % (funcdesc,)) + raise annmodel.AnnotatorError("memo call: no Python function object" + "to call (%r)" % (funcdesc,)) def compute_one_result(args): value = func(*args) @@ -344,8 +345,8 @@ desc, = s.descriptions key.append(desc) else: - raise Exception("specialize:arg(%d): argument not constant: %r" - % (i, s)) + raise annmodel.AnnotatorError("specialize:arg(%d): argument not " + "constant: %r" % (i, s)) key = tuple(key) return maybe_star_args(funcdesc, key, args_s) diff --git a/rpython/jit/metainterp/test/test_ajit.py b/rpython/jit/metainterp/test/test_ajit.py --- a/rpython/jit/metainterp/test/test_ajit.py +++ b/rpython/jit/metainterp/test/test_ajit.py @@ -2386,6 +2386,7 @@ if i >= len(bytecode): break op = bytecode[i] + i += 1 if op == 'j': j += 1 elif op == 'c': @@ -2415,7 +2416,6 @@ else: return ord(op) - i += 1 return 42 assert f() == 42 def g(): 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 @@ -1289,8 +1289,10 @@ frame = Frame(n, 0) somewhere_else.top_frame = frame # escapes frame = hint(frame, access_directly=True) - while frame.x > 0: + while True: myjitdriver.jit_merge_point(frame=frame, fail=fail) + if frame.x <= 0: + break frame.x -= 1 if fail or frame.x > 2: frame.y += frame.x diff --git a/rpython/jit/tl/tl.py b/rpython/jit/tl/tl.py --- a/rpython/jit/tl/tl.py +++ b/rpython/jit/tl/tl.py @@ -77,9 +77,13 @@ stack = hint(stack, access_directly=True) - while pc < len(code): + while True: myjitdriver.jit_merge_point(pc=pc, code=code, stack=stack, inputarg=inputarg) + + if pc >= len(code): + break + opcode = ord(code[pc]) stack.stackpos = promote(stack.stackpos) pc += 1 diff --git a/rpython/rlib/jit.py b/rpython/rlib/jit.py --- a/rpython/rlib/jit.py +++ b/rpython/rlib/jit.py @@ -182,7 +182,6 @@ else: return trampoline(%(arguments)s) f.__name__ = func.__name__ + "_look_inside_iff" - f._always_inline = True """ % {"arguments": ", ".join(args)}).compile() in d return d["f"] return inner @@ -479,6 +478,7 @@ virtualizables = [] name = 'jitdriver' inline_jit_merge_point = False + _store_last_enter_jit = None def __init__(self, greens=None, reds=None, virtualizables=None, get_jitcell_at=None, set_jitcell_at=None, @@ -524,14 +524,14 @@ def _freeze_(self): return True - def _check_arguments(self, livevars): + def _check_arguments(self, livevars, is_merge_point): assert set(livevars) == self._somelivevars # check heuristically that 'reds' and 'greens' are ordered as # the JIT will need them to be: first INTs, then REFs, then # FLOATs. if len(self._heuristic_order) < len(livevars): from rpython.rlib.rarithmetic import (r_singlefloat, r_longlong, - r_ulonglong, r_uint) + r_ulonglong, r_uint) added = False for var, value in livevars.items(): if var not in self._heuristic_order: @@ -572,17 +572,27 @@ "must be INTs, REFs, FLOATs; got %r" % (color, allkinds)) + if is_merge_point: + if self._store_last_enter_jit: + if livevars != self._store_last_enter_jit: + raise JitHintError( + "Bad can_enter_jit() placement: there should *not* " + "be any code in between can_enter_jit() -> jit_merge_point()" ) + self._store_last_enter_jit = None + else: + self._store_last_enter_jit = livevars + def jit_merge_point(_self, **livevars): # special-cased by ExtRegistryEntry if _self.check_untranslated: - _self._check_arguments(livevars) + _self._check_arguments(livevars, True) def can_enter_jit(_self, **livevars): if _self.autoreds: raise TypeError, "Cannot call can_enter_jit on a driver with reds='auto'" # special-cased by ExtRegistryEntry if _self.check_untranslated: - _self._check_arguments(livevars) + _self._check_arguments(livevars, False) def loop_header(self): # special-cased by ExtRegistryEntry diff --git a/rpython/rlib/rsocket.py b/rpython/rlib/rsocket.py --- a/rpython/rlib/rsocket.py +++ b/rpython/rlib/rsocket.py @@ -509,12 +509,13 @@ if hasattr(_c, 'fcntl'): def _setblocking(self, block): - delay_flag = intmask(_c.fcntl(self.fd, _c.F_GETFL, 0)) + orig_delay_flag = intmask(_c.fcntl(self.fd, _c.F_GETFL, 0)) if block: - delay_flag &= ~_c.O_NONBLOCK + delay_flag = orig_delay_flag & ~_c.O_NONBLOCK else: - delay_flag |= _c.O_NONBLOCK - _c.fcntl(self.fd, _c.F_SETFL, delay_flag) + delay_flag = orig_delay_flag | _c.O_NONBLOCK + if orig_delay_flag != delay_flag: + _c.fcntl(self.fd, _c.F_SETFL, delay_flag) elif hasattr(_c, 'ioctlsocket'): def _setblocking(self, block): flag = lltype.malloc(rffi.ULONGP.TO, 1, flavor='raw') diff --git a/rpython/rlib/rstring.py b/rpython/rlib/rstring.py --- a/rpython/rlib/rstring.py +++ b/rpython/rlib/rstring.py @@ -14,7 +14,36 @@ # -------------- public API for string functions ----------------------- @specialize.argtype(0) -def split(value, by, maxsplit=-1): +def split(value, by=None, maxsplit=-1): + if by is None: + length = len(value) + i = 0 + res = [] + while True: + # find the beginning of the next word + while i < length: + if not value[i].isspace(): + break # found + i += 1 + else: + break # end of string, finished + + # find the end of the word + if maxsplit == 0: + j = length # take all the rest of the string + else: + j = i + 1 + while j < length and not value[j].isspace(): + j += 1 + maxsplit -= 1 # NB. if it's already < 0, it stays < 0 + + # the word is value[i:j] + res.append(value[i:j]) + + # continue to look from the character following the space after the word + i = j + 1 + return res + if isinstance(value, str): assert isinstance(by, str) else: @@ -58,7 +87,41 @@ @specialize.argtype(0) -def rsplit(value, by, maxsplit=-1): +def rsplit(value, by=None, maxsplit=-1): + if by is None: + res = [] + + i = len(value) - 1 + while True: + # starting from the end, find the end of the next word + while i >= 0: + if not value[i].isspace(): + break # found + i -= 1 + else: + break # end of string, finished + + # find the start of the word + # (more precisely, 'j' will be the space character before the word) + if maxsplit == 0: + j = -1 # take all the rest of the string + else: + j = i - 1 + while j >= 0 and not value[j].isspace(): + j -= 1 + maxsplit -= 1 # NB. if it's already < 0, it stays < 0 + + # the word is value[j+1:i+1] + j1 = j + 1 + assert j1 >= 0 + res.append(value[j1:i+1]) + + # continue to look from the character before the space before the word + i = j - 1 + + res.reverse() + return res + if isinstance(value, str): assert isinstance(by, str) else: diff --git a/rpython/rlib/test/test_jit.py b/rpython/rlib/test/test_jit.py --- a/rpython/rlib/test/test_jit.py +++ b/rpython/rlib/test/test_jit.py @@ -78,6 +78,19 @@ assert driver2.foo == 'bar' +def test_merge_enter_different(): + myjitdriver = JitDriver(greens=[], reds=['n']) + def fn(n): + while n > 0: + myjitdriver.jit_merge_point(n=n) + myjitdriver.can_enter_jit(n=n) + n -= 1 + return n + py.test.raises(JitHintError, fn, 100) + + myjitdriver = JitDriver(greens=['n'], reds=[]) + py.test.raises(JitHintError, fn, 100) + class TestJIT(BaseRtypingTest): def test_hint(self): def f(): diff --git a/rpython/rlib/test/test_rstring.py b/rpython/rlib/test/test_rstring.py --- a/rpython/rlib/test/test_rstring.py +++ b/rpython/rlib/test/test_rstring.py @@ -16,6 +16,11 @@ assert split('endcase test', 'test') == ['endcase ', ''] py.test.raises(ValueError, split, 'abc', '') +def test_split_None(): + assert split("") == [] + assert split(' a\ta\na b') == ['a', 'a', 'a', 'b'] + assert split(" a a ", maxsplit=1) == ['a', 'a '] + def test_split_unicode(): assert split(u"", u'x') == [u''] assert split(u"a", u"a", 1) == [u'', u''] @@ -37,6 +42,11 @@ assert rsplit('endcase test', 'test') == ['endcase ', ''] py.test.raises(ValueError, rsplit, "abc", '') +def test_rsplit_None(): + assert rsplit("") == [] + assert rsplit(' a\ta\na b') == ['a', 'a', 'a', 'b'] + assert rsplit(" a a ", maxsplit=1) == [' a', 'a'] + def test_rsplit_unicode(): assert rsplit(u"a", u"a", 1) == [u'', u''] assert rsplit(u" ", u" ", 1) == [u'', u''] @@ -168,6 +178,7 @@ def fn(): res = True res = res and split('a//b//c//d', '//') == ['a', 'b', 'c', 'd'] + res = res and split(' a\ta\na b') == ['a', 'a', 'a', 'b'] res = res and split('a//b//c//d', '//', 2) == ['a', 'b', 'c//d'] res = res and split(u'a//b//c//d', u'//') == [u'a', u'b', u'c', u'd'] res = res and split(u'endcase test', u'test') == [u'endcase ', u''] 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 @@ -2,6 +2,7 @@ from rpython.rlib.signature import signature, finishsigs, FieldSpec, ClassSpec from rpython.rlib import types from rpython.annotator import model +from rpython.annotator.signature import SignatureError from rpython.translator.translator import TranslationContext, graphof from rpython.rtyper.lltypesystem import rstr from rpython.rtyper.annlowlevel import LowLevelAnnotatorPolicy @@ -24,8 +25,8 @@ return sigof(a, f) def check_annotator_fails(caller): - exc = py.test.raises(Exception, annotate_at, caller).value - assert caller.func_name in repr(exc.args) + exc = py.test.raises(model.AnnotatorError, annotate_at, caller).value + assert caller.func_name in str(exc) def test_bookkeeping(): @@ -245,9 +246,9 @@ def incomplete_sig_meth(self): pass - 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) + exc = py.test.raises(SignatureError, annotate_at, C.incomplete_sig_meth).value + assert 'incomplete_sig_meth' in str(exc) + assert 'finishsigs' in str(exc) def test_any_as_argument(): @signature(types.any(), types.int(), returns=types.float()) @@ -268,8 +269,8 @@ @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) + exc = py.test.raises(model.AnnotatorError, annotate_at, cannot_add_string).value + assert 'Blocked block' in str(exc) From noreply at buildbot.pypy.org Mon Sep 2 22:37:13 2013 From: noreply at buildbot.pypy.org (mattip) Date: Mon, 2 Sep 2013 22:37:13 +0200 (CEST) Subject: [pypy-commit] pypy default: no _curses module on windows, fix issue 1532 Message-ID: <20130902203713.0A45F1C01F7@cobra.cs.uni-duesseldorf.de> Author: mattip Branch: Changeset: r66776:9e7bb222d72f Date: 2013-09-02 23:36 +0300 http://bitbucket.org/pypy/pypy/changeset/9e7bb222d72f/ Log: no _curses module on windows, fix issue 1532 diff --git a/lib_pypy/_curses.py b/lib_pypy/_curses.py --- a/lib_pypy/_curses.py +++ b/lib_pypy/_curses.py @@ -1,6 +1,9 @@ """Reimplementation of the standard extension module '_curses' using cffi.""" import sys +if sys.platform == 'win32': + #This module does not exist in windows + raise ImportError('No module named _curses') from functools import wraps from cffi import FFI diff --git a/pypy/module/test_lib_pypy/test_curses.py b/pypy/module/test_lib_pypy/test_curses.py --- a/pypy/module/test_lib_pypy/test_curses.py +++ b/pypy/module/test_lib_pypy/test_curses.py @@ -1,4 +1,8 @@ import pytest +import sys +if sys.platform == 'win32': + #This module does not exist in windows + pytest.skip('no curses on windows') # Check that lib_pypy.cffi finds the correct version of _cffi_backend. # Otherwise, the test is skipped. It should never be skipped when run From noreply at buildbot.pypy.org Tue Sep 3 09:11:18 2013 From: noreply at buildbot.pypy.org (arigo) Date: Tue, 3 Sep 2013 09:11:18 +0200 (CEST) Subject: [pypy-commit] cffi default: Tweak: like this, pypy-shadowstack crashes systematically Message-ID: <20130903071118.3FE9E1C0209@cobra.cs.uni-duesseldorf.de> Author: Armin Rigo Branch: Changeset: r1346:6fee32c68e45 Date: 2013-09-03 09:10 +0200 http://bitbucket.org/cffi/cffi/changeset/6fee32c68e45/ Log: Tweak: like this, pypy-shadowstack crashes systematically diff --git a/testing/callback_in_thread.py b/testing/callback_in_thread.py --- a/testing/callback_in_thread.py +++ b/testing/callback_in_thread.py @@ -26,6 +26,7 @@ seen = [] @ffi.callback('int(*)(int,int)') def mycallback(x, y): + time.sleep(0.022) seen.append((x, y)) return 0 lib.threaded_ballback_test(mycallback) From noreply at buildbot.pypy.org Tue Sep 3 09:19:28 2013 From: noreply at buildbot.pypy.org (arigo) Date: Tue, 3 Sep 2013 09:19:28 +0200 (CEST) Subject: [pypy-commit] pypy default: Import cffi/6fee32c68e45 Message-ID: <20130903071928.560E71C0209@cobra.cs.uni-duesseldorf.de> Author: Armin Rigo Branch: Changeset: r66777:ac6fb07dde4e Date: 2013-09-03 09:18 +0200 http://bitbucket.org/pypy/pypy/changeset/ac6fb07dde4e/ Log: Import cffi/6fee32c68e45 diff --git a/lib_pypy/cffi/__init__.py b/lib_pypy/cffi/__init__.py --- a/lib_pypy/cffi/__init__.py +++ b/lib_pypy/cffi/__init__.py @@ -4,5 +4,5 @@ from .api import FFI, CDefError, FFIError from .ffiplatform import VerificationError, VerificationMissing -__version__ = "0.7" -__version_info__ = (0, 7) +__version__ = "0.7.2" +__version_info__ = (0, 7, 2) diff --git a/lib_pypy/cffi/api.py b/lib_pypy/cffi/api.py --- a/lib_pypy/cffi/api.py +++ b/lib_pypy/cffi/api.py @@ -54,7 +54,8 @@ # _cffi_backend.so compiled. import _cffi_backend as backend from . import __version__ - assert backend.__version__ == __version__ + assert (backend.__version__ == __version__ or + backend.__version__ == __version__[:3]) # (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.) diff --git a/lib_pypy/cffi/commontypes.py b/lib_pypy/cffi/commontypes.py --- a/lib_pypy/cffi/commontypes.py +++ b/lib_pypy/cffi/commontypes.py @@ -30,7 +30,9 @@ elif result in model.PrimitiveType.ALL_PRIMITIVE_TYPES: result = model.PrimitiveType(result) else: - assert commontype != result + if commontype == result: + raise api.FFIError("Unsupported type: %r. Please file a bug " + "if you think it should be." % (commontype,)) result = resolve_common_type(result) # recursively assert isinstance(result, model.BaseTypeByIdentity) _CACHE[commontype] = result diff --git a/lib_pypy/cffi/cparser.py b/lib_pypy/cffi/cparser.py --- a/lib_pypy/cffi/cparser.py +++ b/lib_pypy/cffi/cparser.py @@ -290,13 +290,26 @@ # assume a primitive type. get it from .names, but reduce # synonyms to a single chosen combination names = list(type.names) - if names == ['signed'] or names == ['unsigned']: - names.append('int') - if names[0] == 'signed' and names != ['signed', 'char']: - names.pop(0) - if (len(names) > 1 and names[-1] == 'int' - and names != ['unsigned', 'int']): - names.pop() + if names != ['signed', 'char']: # keep this unmodified + prefixes = {} + while names: + name = names[0] + if name in ('short', 'long', 'signed', 'unsigned'): + prefixes[name] = prefixes.get(name, 0) + 1 + del names[0] + else: + break + # ignore the 'signed' prefix below, and reorder the others + newnames = [] + for prefix in ('unsigned', 'short', 'long'): + for i in range(prefixes.get(prefix, 0)): + newnames.append(prefix) + if not names: + names = ['int'] # implicitly + if names == ['int']: # but kill it if 'short' or 'long' + if 'short' in prefixes or 'long' in prefixes: + names = [] + names = newnames + names ident = ' '.join(names) if ident == 'void': return model.void_type @@ -500,8 +513,8 @@ self._partial_length = True return None # - raise api.FFIError("unsupported non-constant or " - "not immediately constant expression") + raise api.FFIError("unsupported expression: expected a " + "simple numeric constant") def _build_enum_type(self, explicit_name, decls): if decls is not None: diff --git a/lib_pypy/cffi/vengine_gen.py b/lib_pypy/cffi/vengine_gen.py --- a/lib_pypy/cffi/vengine_gen.py +++ b/lib_pypy/cffi/vengine_gen.py @@ -61,7 +61,9 @@ def load_library(self): # import it with the CFFI backend backend = self.ffi._backend - module = backend.load_library(self.verifier.modulefilename) + # needs to make a path that contains '/', on Posix + filename = os.path.join(os.curdir, self.verifier.modulefilename) + module = backend.load_library(filename) # # call loading_gen_struct() to get the struct layout inferred by # the C compiler diff --git a/pypy/module/test_lib_pypy/cffi_tests/backend_tests.py b/pypy/module/test_lib_pypy/cffi_tests/backend_tests.py --- a/pypy/module/test_lib_pypy/cffi_tests/backend_tests.py +++ b/pypy/module/test_lib_pypy/cffi_tests/backend_tests.py @@ -199,6 +199,9 @@ typerepr = self.TypeRepr ffi = FFI(backend=self.Backend()) ffi.cdef("struct foo { short a, b, c; };") + p = ffi.cast("short unsigned int", 0) + assert repr(p) == "" + assert repr(ffi.typeof(p)) == typerepr % "unsigned short" p = ffi.cast("unsigned short int", 0) assert repr(p) == "" assert repr(ffi.typeof(p)) == typerepr % "unsigned short" @@ -535,13 +538,13 @@ for c_type, expected_size in [ ('char', 1), ('unsigned int', 4), - ('char *', SIZE_OF_LONG), + ('char *', SIZE_OF_PTR), ('int[5]', 20), ('struct foo', 12), ('union foo', 4), ]: size = ffi.sizeof(c_type) - assert size == expected_size + assert size == expected_size, (size, expected_size, ctype) def test_sizeof_cdata(self): ffi = FFI(backend=self.Backend()) diff --git a/pypy/module/test_lib_pypy/cffi_tests/callback_in_thread.py b/pypy/module/test_lib_pypy/cffi_tests/callback_in_thread.py --- a/pypy/module/test_lib_pypy/cffi_tests/callback_in_thread.py +++ b/pypy/module/test_lib_pypy/cffi_tests/callback_in_thread.py @@ -27,6 +27,7 @@ seen = [] @ffi.callback('int(*)(int,int)') def mycallback(x, y): + time.sleep(0.022) seen.append((x, y)) return 0 lib.threaded_ballback_test(mycallback) diff --git a/pypy/module/test_lib_pypy/cffi_tests/test_function.py b/pypy/module/test_lib_pypy/cffi_tests/test_function.py --- a/pypy/module/test_lib_pypy/cffi_tests/test_function.py +++ b/pypy/module/test_lib_pypy/cffi_tests/test_function.py @@ -382,3 +382,26 @@ sin100 = my_decorator(m.sin) x = sin100(1.23) assert x == math.sin(1.23) + 100 + + def test_free_callback_cycle(self): + if self.Backend is CTypesBackend: + py.test.skip("seems to fail with the ctypes backend on windows") + import weakref + def make_callback(data): + container = [data] + callback = ffi.callback('int()', lambda: len(container)) + container.append(callback) + # Ref cycle: callback -> lambda (closure) -> container -> callback + return callback + + class Data(object): + pass + ffi = FFI(backend=self.Backend()) + data = Data() + callback = make_callback(data) + wr = weakref.ref(data) + del callback, data + for i in range(3): + if wr() is not None: + import gc; gc.collect() + assert wr() is None # 'data' does not leak diff --git a/pypy/module/test_lib_pypy/cffi_tests/test_version.py b/pypy/module/test_lib_pypy/cffi_tests/test_version.py --- a/pypy/module/test_lib_pypy/cffi_tests/test_version.py +++ b/pypy/module/test_lib_pypy/cffi_tests/test_version.py @@ -8,6 +8,8 @@ BACKEND_VERSIONS = { '0.4.2': '0.4', # did not change + '0.7.1': '0.7', # did not change + '0.7.2': '0.7', # did not change } def test_version(): @@ -22,7 +24,7 @@ content = open(p).read() # v = cffi.__version__ - assert ("version = '%s'\n" % v) in content + assert ("version = '%s'\n" % BACKEND_VERSIONS.get(v, v)) in content assert ("release = '%s'\n" % v) in content def test_doc_version_file(): @@ -45,4 +47,5 @@ v = cffi.__version__ p = os.path.join(parent, 'c', 'test_c.py') content = open(p).read() - assert ('assert __version__ == "%s"' % v) in content + assert (('assert __version__ == "%s"' % BACKEND_VERSIONS.get(v, v)) + in content) From noreply at buildbot.pypy.org Tue Sep 3 09:37:06 2013 From: noreply at buildbot.pypy.org (arigo) Date: Tue, 3 Sep 2013 09:37:06 +0200 (CEST) Subject: [pypy-commit] pypy default: Kill the 'gc_thread_prepare' llop, which is anyway turned to nothing Message-ID: <20130903073706.42AF11C0209@cobra.cs.uni-duesseldorf.de> Author: Armin Rigo Branch: Changeset: r66778:31deb9a89134 Date: 2013-09-03 09:31 +0200 http://bitbucket.org/pypy/pypy/changeset/31deb9a89134/ Log: Kill the 'gc_thread_prepare' llop, which is anyway turned to nothing diff --git a/pypy/module/cpyext/pystate.py b/pypy/module/cpyext/pystate.py --- a/pypy/module/cpyext/pystate.py +++ b/pypy/module/cpyext/pystate.py @@ -241,7 +241,6 @@ it is necessary to serialize calls to this function.""" if not space.config.translation.thread: raise NoThreads - rthread.gc_thread_prepare() # PyThreadState_Get will allocate a new execution context, # we need to protect gc and other globals with the GIL. rffi.aroundstate.after() 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 @@ -182,7 +182,6 @@ bootstrapper.acquire(space, w_callable, args) try: try: - rthread.gc_thread_prepare() # (this has no effect any more) ident = rthread.start_new_thread(bootstrapper.bootstrap, ()) except Exception: bootstrapper.release() # normally called by the new thread diff --git a/pypy/module/thread/test/test_gil.py b/pypy/module/thread/test/test_gil.py --- a/pypy/module/thread/test/test_gil.py +++ b/pypy/module/thread/test/test_gil.py @@ -72,7 +72,6 @@ state.datalen4 = 0 state.threadlocals = gil.GILThreadLocals() state.threadlocals.setup_threads(space) - thread.gc_thread_prepare() subident = thread.start_new_thread(bootstrap, ()) mainident = thread.get_ident() runme(True) 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 @@ -974,9 +974,6 @@ self.c_const_gc, v_size]) - def gct_gc_thread_prepare(self, hop): - pass # no effect any more - def gct_gc_thread_run(self, hop): assert self.translator.config.translation.thread if hasattr(self.root_walker, 'thread_run_ptr'): diff --git a/rpython/rlib/rthread.py b/rpython/rlib/rthread.py --- a/rpython/rlib/rthread.py +++ b/rpython/rlib/rthread.py @@ -205,18 +205,7 @@ # ____________________________________________________________ # # Thread integration. -# These are six completely ad-hoc operations at the moment. - - at jit.dont_look_inside -def gc_thread_prepare(): - """To call just before thread.start_new_thread(). This - allocates a new shadow stack to be used by the future - thread. If memory runs out, this raises a MemoryError - (which can be handled by the caller instead of just getting - ignored if it was raised in the newly starting thread). - """ - if we_are_translated(): - llop.gc_thread_prepare(lltype.Void) +# These are five completely ad-hoc operations at the moment. @jit.dont_look_inside def gc_thread_run(): diff --git a/rpython/rlib/test/test_rthread.py b/rpython/rlib/test/test_rthread.py --- a/rpython/rlib/test/test_rthread.py +++ b/rpython/rlib/test/test_rthread.py @@ -117,7 +117,6 @@ def g(i, j): state.bootstrapping.acquire(True) state.z = Z(i, j) - gc_thread_prepare() start_new_thread(bootstrap, ()) def f(): diff --git a/rpython/rtyper/llinterp.py b/rpython/rtyper/llinterp.py --- a/rpython/rtyper/llinterp.py +++ b/rpython/rtyper/llinterp.py @@ -784,9 +784,6 @@ addr = llmemory.cast_ptr_to_adr(ptr) return self.heap.can_move(addr) - def op_gc_thread_prepare(self): - self.heap.thread_prepare() - def op_gc_thread_run(self): self.heap.thread_run() diff --git a/rpython/rtyper/lltypesystem/llheap.py b/rpython/rtyper/lltypesystem/llheap.py --- a/rpython/rtyper/lltypesystem/llheap.py +++ b/rpython/rtyper/lltypesystem/llheap.py @@ -24,9 +24,6 @@ return False -def thread_prepare(): - pass - def thread_run(): 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 @@ -471,7 +471,6 @@ 'gc_obtain_free_space': LLOp(), 'gc_set_max_heap_size': LLOp(), 'gc_can_move' : LLOp(sideeffects=False), - 'gc_thread_prepare' : LLOp(canmallocgc=True), 'gc_thread_run' : LLOp(), 'gc_thread_start' : LLOp(), 'gc_thread_die' : LLOp(), diff --git a/rpython/translator/c/test/test_standalone.py b/rpython/translator/c/test/test_standalone.py --- a/rpython/translator/c/test/test_standalone.py +++ b/rpython/translator/c/test/test_standalone.py @@ -1070,7 +1070,6 @@ rthread.gc_thread_die() def new_thread(): - rthread.gc_thread_prepare() ident = rthread.start_new_thread(bootstrap, ()) time.sleep(0.5) # enough time to start, hopefully return ident @@ -1198,7 +1197,6 @@ rthread.gc_thread_die() def new_thread(): - rthread.gc_thread_prepare() ident = rthread.start_new_thread(bootstrap, ()) time.sleep(0.5) # enough time to start, hopefully return ident From noreply at buildbot.pypy.org Tue Sep 3 10:49:12 2013 From: noreply at buildbot.pypy.org (toastdriven) Date: Tue, 3 Sep 2013 10:49:12 +0200 (CEST) Subject: [pypy-commit] benchmarks deltablue: Added the deltablue benchmark. Message-ID: <20130903084912.0F21B1C0270@cobra.cs.uni-duesseldorf.de> Author: Daniel Lindsley Branch: deltablue Changeset: r230:7c266c787055 Date: 2013-09-01 18:17 -0700 http://bitbucket.org/pypy/benchmarks/changeset/7c266c787055/ Log: Added the deltablue benchmark. diff --git a/benchmarks.py b/benchmarks.py --- a/benchmarks.py +++ b/benchmarks.py @@ -80,7 +80,7 @@ for name in ['float', 'nbody_modified', 'meteor-contest', 'fannkuch', 'spectral-norm', 'chaos', 'telco', 'go', 'pyflate-fast', 'raytrace-simple', 'crypto_pyaes', 'bm_mako', 'bm_chameleon', - 'json_bench', 'pidigits', 'hexiom2', 'eparse']: + 'json_bench', 'pidigits', 'hexiom2', 'eparse', 'deltablue']: _register_new_bm(name, name, globals(), **opts.get(name, {})) for name in ['names', 'iteration', 'tcp', 'pb', ]:#'web']:#, 'accepts']: diff --git a/own/deltablue.py b/own/deltablue.py new file mode 100644 --- /dev/null +++ b/own/deltablue.py @@ -0,0 +1,642 @@ +""" +deltablue.py +============ + +Ported for the PyPy project. +Contributed by Daniel Lindsley + +This implementation of the DeltaBlue benchmark was directly ported +from the `V8's source code`_, which was in turn derived +from the Smalltalk implementation by John Maloney and Mario +Wolczko. The original Javascript implementation was licensed under the GPL. + +It's been updated in places to be more idiomatic to Python (for loops over +collections, a couple magic methods, ``OrderedCollection`` being a list & things +altering those collections changed to the builtin methods) but largely retains +the layout & logic from the original. (Ugh.) + +.. _`V8's source code`: (http://code.google.com/p/v8/source/browse/branches/bleeding_edge/benchmarks/deltablue.js) + +""" +from __future__ import print_function + + +# The JS variant implements "OrderedCollection", which basically completely +# overlaps with ``list``. So we'll cheat. :D +class OrderedCollection(list): + pass + + +class Strength(object): + REQUIRED = None + STRONG_PREFERRED = None + PREFERRED = None + STRONG_DEFAULT = None + NORMAL = None + WEAK_DEFAULT = None + WEAKEST = None + + def __init__(self, strength, name): + super(Strength, self).__init__() + self.strength = strength + self.name = name + + @classmethod + def stronger(cls, s1, s2): + return s1.strength < s2.strength + + @classmethod + def weaker(cls, s1, s2): + return s1.strength > s2.strength + + @classmethod + def weakest_of(cls, s1, s2): + if cls.weaker(s1, s2): + return s1 + + return s2 + + @classmethod + def strongest(cls, s1, s2): + if cls.stronger(s1, s2): + return s1 + + return s2 + + def next_weaker(self): + strengths = { + 0: self.__class__.WEAKEST, + 1: self.__class__.WEAK_DEFAULT, + 2: self.__class__.NORMAL, + 3: self.__class__.STRONG_DEFAULT, + 4: self.__class__.PREFERRED, + # TODO: This looks like a bug in the original code. Shouldn't this be + # ``STRONG_PREFERRED? Keeping for porting sake... + 5: self.__class__.REQUIRED, + } + return strengths[self.strength] + + +# This is a terrible pattern IMO, but true to the original JS implementation. +Strength.REQUIRED = Strength(0, "required") +Strength.STONG_PREFERRED = Strength(1, "strongPreferred") +Strength.PREFERRED = Strength(2, "preferred") +Strength.STRONG_DEFAULT = Strength(3, "strongDefault") +Strength.NORMAL = Strength(4, "normal") +Strength.WEAK_DEFAULT = Strength(5, "weakDefault") +Strength.WEAKEST = Strength(6, "weakest") + + +class Constraint(object): + def __init__(self, strength): + super(Constraint, self).__init__() + self.strength = strength + + def add_constraint(self): + global planner + self.add_to_graph() + planner.incremental_add(self) + + def satisfy(self, mark): + global planner + self.choose_method(mark) + + if not self.is_satisfied(): + if self.strength == Strength.REQUIRED: + print('Could not satisfy a required constraint!') + + return None + + self.mark_inputs(mark) + out = self.output() + overridden = out.determined_by + + if overridden is not None: + overridden.mark_unsatisfied() + + out.determined_by = self + + if not planner.add_propagate(self, mark): + print('Cycle encountered') + + out.mark = mark + return overridden + + def destroy_constraint(self): + global planner + if self.is_satisfied(): + planner.incremental_remove(self) + else: + self.remove_from_graph() + + def is_input(self): + return False + + +class UrnaryConstraint(Constraint): + def __init__(self, v, strength): + super(UrnaryConstraint, self).__init__(strength) + self.my_output = v + self.satisfied = False + self.add_constraint() + + def add_to_graph(self): + self.my_output.add_constraint(self) + self.satisfied = False + + def choose_method(self, mark): + if self.my_output.mark != mark and \ + Strength.stronger(self.strength, self.my_output.walk_strength): + self.satisfied = True + else: + self.satisfied = False + + def is_satisfied(self): + return self.satisfied + + def mark_inputs(self, mark): + # No-ops. + pass + + def output(self): + # Ugh. Keeping it for consistency with the original. So much for + # "we're all adults here"... + return self.my_output + + def recalculate(self): + self.my_output.walk_strength = self.strength + self.my_output.stay = not self.is_input() + + if self.my_output.stay: + self.execute() + + def mark_unsatisfied(self): + self.satisfied = False + + def inputs_known(self, mark): + return True + + def remove_from_graph(self): + if self.my_output is not None: + self.my_output.remove_constraint(self) + self.satisfied = False + + +class StayConstraint(UrnaryConstraint): + def __init__(self, v, string): + super(StayConstraint, self).__init__(v, string) + + def execute(self): + # The methods, THEY DO NOTHING. + pass + + +class EditConstraint(UrnaryConstraint): + def __init__(self, v, string): + super(EditConstraint, self).__init__(v, string) + + def is_input(self): + return True + + def execute(self): + # This constraint also does nothing. + pass + + +class Direction(object): + # Hooray for things that ought to be structs! + NONE = 0 + FORWARD = 1 + BACKWARD = -1 + + +class BinaryConstraint(Constraint): + def __init__(self, v1, v2, strength): + super(BinaryConstraint, self).__init__(strength) + self.v1 = v1 + self.v2 = v2 + self.direction = Direction.NONE + self.add_constraint() + + def choose_method(self, mark): + if self.v1.mark == mark: + if self.v2.mark != mark and Strength.stronger(self.strength, self.v2.walk_strength): + self.direction = Direction.FORWARD + else: + self.direction = Direction.BACKWARD + + if self.v2.mark == mark: + if self.v1.mark != mark and Strength.stronger(self.strength, self.v1.walk_strength): + self.direction = Direction.BACKWARD + else: + self.direction = Direction.NONE + + if Strength.weaker(self.v1.walk_strength, self.v2.walk_strength): + if Strength.stronger(self.strength, self.v1.walk_strength): + self.direction = Direction.BACKWARD + else: + self.direction = Direction.NONE + else: + if Strength.stronger(self.strength, self.v2.walk_strength): + self.direction = Direction.FORWARD + else: + self.direction = Direction.BACKWARD + + def add_to_graph(self): + self.v1.add_constraint(self) + self.v2.add_constraint(self) + self.direction = Direction.NONE + + def is_satisfied(self): + return self.direction != Direction.NONE + + def mark_inputs(self, mark): + self.input().mark = mark + + def input(self): + if self.direction == Direction.FORWARD: + return self.v1 + + return self.v2 + + def output(self): + if self.direction == Direction.FORWARD: + return self.v2 + + return self.v1 + + def recalculate(self): + ihn = self.input() + out = self.output() + out.walk_strength = Strength.weakest_of(self.strength, ihn.walk_strength) + out.stay = ihn.stay + + if out.stay: + self.execute() + + def mark_unsatisfied(self): + self.direction = Direction.NONE + + def inputs_known(self, mark): + i = self.input() + return i.mark == mark or i.stay or i.determined_by == None + + def remove_from_graph(self): + if self.v1 is not None: + self.v1.remove_constraint(self) + + if self.v2 is not None: + self.v2.remove_constraint(self) + + self.direction = Direction.NONE + + +class ScaleConstraint(BinaryConstraint): + def __init__(self, src, scale, offset, dest, strength): + self.direction = Direction.NONE + self.scale = scale + self.offset = offset + super(ScaleConstraint, self).__init__(src, dest, strength) + + def add_to_graph(self): + super(ScaleConstraint, self).add_to_graph() + self.scale.add_constraint(self) + self.offset.add_constraint(self) + + def remove_from_graph(self): + super(ScaleConstraint, self).remove_from_graph() + + if self.scale is not None: + self.scale.remove_constraint(self) + + if self.offset is not None: + self.offset.remove_constraint(self) + + def mark_inputs(self, mark): + super(ScaleConstraint, self).mark_inputs(mark) + self.scale.mark = mark + self.offset.mark = mark + + def execute(self): + if self.direction == Direction.FORWARD: + self.v2.value = self.v1.value * self.scale.value + self.offset.value + else: + self.v1.value = (self.v2.value - self.offset.value) / self.scale.value + + def recalculate(self): + ihn = self.input() + out = self.output() + out.walk_strength = Strength.weakest_of(self.strength, ihn.walk_strength) + out.stay = ihn.stay and self.scale.stay and self.offset.stay + + if out.stay: + self.execute() + + +class EqualityConstraint(BinaryConstraint): + def execute(self): + self.output().value = self.input().value + + +class Variable(object): + def __init__(self, name, initial_value=0): + super(Variable, self).__init__() + self.name = name + self.value = initial_value + self.constraints = OrderedCollection() + self.determined_by = None + self.mark = 0 + self.walk_strength = Strength.WEAKEST + self.stay = True + + def __repr__(self): + # To make debugging this beast from pdb easier... + return '' % ( + self.name, + self.value + ) + + def add_constraint(self, constraint): + self.constraints.append(constraint) + + def remove_constraint(self, constraint): + self.constraints.remove(constraint) + + if self.determined_by == constraint: + self.determined_by = None + + +class Planner(object): + def __init__(self): + super(Planner, self).__init__() + self.current_mark = 0 + + def incremental_add(self, constraint): + mark = self.new_mark() + overridden = constraint.satisfy(mark) + + while overridden is not None: + overridden = overridden.satisfy(mark) + + def incremental_remove(self, constraint): + out = constraint.output() + constraint.mark_unsatisfied() + constraint.remove_from_graph() + unsatisfied = self.remove_propagate_from(out) + strength = Strength.REQUIRED + # Do-while, the Python way. + repeat = True + + while repeat: + for u in unsatisfied: + if u.strength == strength: + self.incremental_add(u) + + strength = strength.next_weaker() + + repeat = strength != Strength.WEAKEST + + def new_mark(self): + self.current_mark += 1 + return self.current_mark + + def make_plan(self, sources): + mark = self.new_mark() + plan = Plan() + todo = sources + + while len(todo): + c = todo.pop(0) + + if c.output().mark != mark and c.inputs_known(mark): + plan.add_constraint(c) + c.output().mark = mark + self.add_constraints_consuming_to(c.output(), todo) + + return plan + + def extract_plan_from_constraints(self, constraints): + sources = OrderedCollection() + + for c in constraints: + if c.is_input() and c.is_satisfied(): + sources.append(c) + + return self.make_plan(sources) + + def add_propagate(self, c, mark): + todo = OrderedCollection() + todo.append(c) + + while len(todo): + d = todo.pop(0) + + if d.output().mark == mark: + self.incremental_remove(c) + return False + + d.recalculate() + self.add_constraints_consuming_to(d.output(), todo) + + return True + + def remove_propagate_from(self, out): + out.determined_by = None + out.walk_strength = Strength.WEAKEST + out.stay = True + unsatisfied = OrderedCollection() + todo = OrderedCollection() + todo.append(out) + + while len(todo): + v = todo.pop(0) + + for c in v.constraints: + if not c.is_satisfied(): + unsatisfied.append(c) + + determining = v.determined_by + + for c in v.constraints: + if c != determining and c.is_satisfied(): + c.recalculate() + todo.append(c.output()) + + return unsatisfied + + def add_constraints_consuming_to(self, v, coll): + determining = v.determined_by + cc = v.constraints + + for c in cc: + if c != determining and c.is_satisfied(): + # I guess we're just updating a reference (``coll``)? Seems + # inconsistent with the rest of the implementation, where they + # return the lists... + coll.append(c) + + +class Plan(object): + def __init__(self): + super(Plan, self).__init__() + self.v = OrderedCollection() + + def add_constraint(self, c): + self.v.append(c) + + def __len__(self): + return len(self.v) + + def __getitem__(self, index): + return self.v[index] + + def execute(self): + for c in self.v: + c.execute() + + +# Main + +def chain_test(n): + """ + This is the standard DeltaBlue benchmark. A long chain of equality + constraints is constructed with a stay constraint on one end. An + edit constraint is then added to the opposite end and the time is + measured for adding and removing this constraint, and extracting + and executing a constraint satisfaction plan. There are two cases. + In case 1, the added constraint is stronger than the stay + constraint and values must propagate down the entire length of the + chain. In case 2, the added constraint is weaker than the stay + constraint so it cannot be accomodated. The cost in this case is, + of course, very low. Typical situations lie somewhere between these + two extremes. + """ + global planner + planner = Planner() + prev, first, last = None, None, None + + # We need to go up to n inclusively. + for i in range(n + 1): + name = "v%s" % i + v = Variable(name) + + if prev is not None: + EqualityConstraint(prev, v, Strength.REQUIRED) + + if i == 0: + first = v + + if i == n: + last = v + + prev = v + + StayConstraint(last, Strength.STRONG_DEFAULT) + edit = EditConstraint(first, Strength.PREFERRED) + edits = OrderedCollection() + edits.append(edit) + plan = planner.extract_plan_from_constraints(edits) + + for i in range(100): + first.value = i + plan.execute() + + if last.value != i: + print("Chain test failed.") + + +def projection_test(n): + """ + This test constructs a two sets of variables related to each + other by a simple linear transformation (scale and offset). The + time is measured to change a variable on either side of the + mapping and to change the scale and offset factors. + """ + global planner + planner = Planner() + scale = Variable("scale", 10) + offset = Variable("offset", 1000) + src, dest = None, None + + dests = OrderedCollection() + + for i in range(n): + src = Variable("src%s" % i, i) + dst = Variable("dst%s" % i, i) + dests.append(dst) + StayConstraint(src, Strength.NORMAL) + ScaleConstraint(src, scale, offset, dst, Strength.REQUIRED) + + change(src, 17) + + if dst.value != 1170: + print("Projection 1 failed") + + change(dst, 1050) + + if src.value != 5: + print("Projection 2 failed") + + change(scale, 5) + + for i in range(n - 1): + if dests[i].value != (i * 5 + 1000): + print("Projection 3 failed") + + change(offset, 2000) + + for i in range(n - 1): + if dests[i].value != (i * 5 + 2000): + print("Projection 4 failed") + + +def change(v, new_value): + global planner + edit = EditConstraint(v, Strength.PREFERRED) + edits = OrderedCollection() + edits.append(edit) + + plan = planner.extract_plan_from_constraints(edits) + + for i in range(10): + v.value = new_value + plan.execute() + + edit.destroy_constraint() + + +# HOORAY FOR GLOBALS... Oh wait. +# In spirit of the original, we'll keep it, but ugh. +planner = None + + +def delta_blue(): + chain_test(100) + projection_test(100) + + +# Specific to the PyPy implementation, to run within the main harnass. +def main(n): + import time + times = [] + + for i in range(n): + t1 = time.time() + delta_blue() + t2 = time.time() + times.append(t2 - t1) + + return times + + +if __name__ == '__main__': + import util + import optparse + + parser = optparse.OptionParser( + usage="%prog [options]", + description="Test the performance of the DeltaBlue benchmark") + util.add_standard_options_to(parser) + options, args = parser.parse_args() + + util.run_benchmark(options, options.num_runs, main) From noreply at buildbot.pypy.org Tue Sep 3 10:49:13 2013 From: noreply at buildbot.pypy.org (fijal) Date: Tue, 3 Sep 2013 10:49:13 +0200 (CEST) Subject: [pypy-commit] benchmarks default: Merged in toastdriven/benchmarks/deltablue (pull request #6) Message-ID: <20130903084913.A7DB11C0270@cobra.cs.uni-duesseldorf.de> Author: Maciej Fijalkowski Branch: Changeset: r231:2e8d214bc738 Date: 2013-09-03 10:49 +0200 http://bitbucket.org/pypy/benchmarks/changeset/2e8d214bc738/ Log: Merged in toastdriven/benchmarks/deltablue (pull request #6) Added the deltablue benchmark. diff --git a/benchmarks.py b/benchmarks.py --- a/benchmarks.py +++ b/benchmarks.py @@ -80,7 +80,7 @@ for name in ['float', 'nbody_modified', 'meteor-contest', 'fannkuch', 'spectral-norm', 'chaos', 'telco', 'go', 'pyflate-fast', 'raytrace-simple', 'crypto_pyaes', 'bm_mako', 'bm_chameleon', - 'json_bench', 'pidigits', 'hexiom2', 'eparse']: + 'json_bench', 'pidigits', 'hexiom2', 'eparse', 'deltablue']: _register_new_bm(name, name, globals(), **opts.get(name, {})) for name in ['names', 'iteration', 'tcp', 'pb', ]:#'web']:#, 'accepts']: diff --git a/own/deltablue.py b/own/deltablue.py new file mode 100644 --- /dev/null +++ b/own/deltablue.py @@ -0,0 +1,642 @@ +""" +deltablue.py +============ + +Ported for the PyPy project. +Contributed by Daniel Lindsley + +This implementation of the DeltaBlue benchmark was directly ported +from the `V8's source code`_, which was in turn derived +from the Smalltalk implementation by John Maloney and Mario +Wolczko. The original Javascript implementation was licensed under the GPL. + +It's been updated in places to be more idiomatic to Python (for loops over +collections, a couple magic methods, ``OrderedCollection`` being a list & things +altering those collections changed to the builtin methods) but largely retains +the layout & logic from the original. (Ugh.) + +.. _`V8's source code`: (http://code.google.com/p/v8/source/browse/branches/bleeding_edge/benchmarks/deltablue.js) + +""" +from __future__ import print_function + + +# The JS variant implements "OrderedCollection", which basically completely +# overlaps with ``list``. So we'll cheat. :D +class OrderedCollection(list): + pass + + +class Strength(object): + REQUIRED = None + STRONG_PREFERRED = None + PREFERRED = None + STRONG_DEFAULT = None + NORMAL = None + WEAK_DEFAULT = None + WEAKEST = None + + def __init__(self, strength, name): + super(Strength, self).__init__() + self.strength = strength + self.name = name + + @classmethod + def stronger(cls, s1, s2): + return s1.strength < s2.strength + + @classmethod + def weaker(cls, s1, s2): + return s1.strength > s2.strength + + @classmethod + def weakest_of(cls, s1, s2): + if cls.weaker(s1, s2): + return s1 + + return s2 + + @classmethod + def strongest(cls, s1, s2): + if cls.stronger(s1, s2): + return s1 + + return s2 + + def next_weaker(self): + strengths = { + 0: self.__class__.WEAKEST, + 1: self.__class__.WEAK_DEFAULT, + 2: self.__class__.NORMAL, + 3: self.__class__.STRONG_DEFAULT, + 4: self.__class__.PREFERRED, + # TODO: This looks like a bug in the original code. Shouldn't this be + # ``STRONG_PREFERRED? Keeping for porting sake... + 5: self.__class__.REQUIRED, + } + return strengths[self.strength] + + +# This is a terrible pattern IMO, but true to the original JS implementation. +Strength.REQUIRED = Strength(0, "required") +Strength.STONG_PREFERRED = Strength(1, "strongPreferred") +Strength.PREFERRED = Strength(2, "preferred") +Strength.STRONG_DEFAULT = Strength(3, "strongDefault") +Strength.NORMAL = Strength(4, "normal") +Strength.WEAK_DEFAULT = Strength(5, "weakDefault") +Strength.WEAKEST = Strength(6, "weakest") + + +class Constraint(object): + def __init__(self, strength): + super(Constraint, self).__init__() + self.strength = strength + + def add_constraint(self): + global planner + self.add_to_graph() + planner.incremental_add(self) + + def satisfy(self, mark): + global planner + self.choose_method(mark) + + if not self.is_satisfied(): + if self.strength == Strength.REQUIRED: + print('Could not satisfy a required constraint!') + + return None + + self.mark_inputs(mark) + out = self.output() + overridden = out.determined_by + + if overridden is not None: + overridden.mark_unsatisfied() + + out.determined_by = self + + if not planner.add_propagate(self, mark): + print('Cycle encountered') + + out.mark = mark + return overridden + + def destroy_constraint(self): + global planner + if self.is_satisfied(): + planner.incremental_remove(self) + else: + self.remove_from_graph() + + def is_input(self): + return False + + +class UrnaryConstraint(Constraint): + def __init__(self, v, strength): + super(UrnaryConstraint, self).__init__(strength) + self.my_output = v + self.satisfied = False + self.add_constraint() + + def add_to_graph(self): + self.my_output.add_constraint(self) + self.satisfied = False + + def choose_method(self, mark): + if self.my_output.mark != mark and \ + Strength.stronger(self.strength, self.my_output.walk_strength): + self.satisfied = True + else: + self.satisfied = False + + def is_satisfied(self): + return self.satisfied + + def mark_inputs(self, mark): + # No-ops. + pass + + def output(self): + # Ugh. Keeping it for consistency with the original. So much for + # "we're all adults here"... + return self.my_output + + def recalculate(self): + self.my_output.walk_strength = self.strength + self.my_output.stay = not self.is_input() + + if self.my_output.stay: + self.execute() + + def mark_unsatisfied(self): + self.satisfied = False + + def inputs_known(self, mark): + return True + + def remove_from_graph(self): + if self.my_output is not None: + self.my_output.remove_constraint(self) + self.satisfied = False + + +class StayConstraint(UrnaryConstraint): + def __init__(self, v, string): + super(StayConstraint, self).__init__(v, string) + + def execute(self): + # The methods, THEY DO NOTHING. + pass + + +class EditConstraint(UrnaryConstraint): + def __init__(self, v, string): + super(EditConstraint, self).__init__(v, string) + + def is_input(self): + return True + + def execute(self): + # This constraint also does nothing. + pass + + +class Direction(object): + # Hooray for things that ought to be structs! + NONE = 0 + FORWARD = 1 + BACKWARD = -1 + + +class BinaryConstraint(Constraint): + def __init__(self, v1, v2, strength): + super(BinaryConstraint, self).__init__(strength) + self.v1 = v1 + self.v2 = v2 + self.direction = Direction.NONE + self.add_constraint() + + def choose_method(self, mark): + if self.v1.mark == mark: + if self.v2.mark != mark and Strength.stronger(self.strength, self.v2.walk_strength): + self.direction = Direction.FORWARD + else: + self.direction = Direction.BACKWARD + + if self.v2.mark == mark: + if self.v1.mark != mark and Strength.stronger(self.strength, self.v1.walk_strength): + self.direction = Direction.BACKWARD + else: + self.direction = Direction.NONE + + if Strength.weaker(self.v1.walk_strength, self.v2.walk_strength): + if Strength.stronger(self.strength, self.v1.walk_strength): + self.direction = Direction.BACKWARD + else: + self.direction = Direction.NONE + else: + if Strength.stronger(self.strength, self.v2.walk_strength): + self.direction = Direction.FORWARD + else: + self.direction = Direction.BACKWARD + + def add_to_graph(self): + self.v1.add_constraint(self) + self.v2.add_constraint(self) + self.direction = Direction.NONE + + def is_satisfied(self): + return self.direction != Direction.NONE + + def mark_inputs(self, mark): + self.input().mark = mark + + def input(self): + if self.direction == Direction.FORWARD: + return self.v1 + + return self.v2 + + def output(self): + if self.direction == Direction.FORWARD: + return self.v2 + + return self.v1 + + def recalculate(self): + ihn = self.input() + out = self.output() + out.walk_strength = Strength.weakest_of(self.strength, ihn.walk_strength) + out.stay = ihn.stay + + if out.stay: + self.execute() + + def mark_unsatisfied(self): + self.direction = Direction.NONE + + def inputs_known(self, mark): + i = self.input() + return i.mark == mark or i.stay or i.determined_by == None + + def remove_from_graph(self): + if self.v1 is not None: + self.v1.remove_constraint(self) + + if self.v2 is not None: + self.v2.remove_constraint(self) + + self.direction = Direction.NONE + + +class ScaleConstraint(BinaryConstraint): + def __init__(self, src, scale, offset, dest, strength): + self.direction = Direction.NONE + self.scale = scale + self.offset = offset + super(ScaleConstraint, self).__init__(src, dest, strength) + + def add_to_graph(self): + super(ScaleConstraint, self).add_to_graph() + self.scale.add_constraint(self) + self.offset.add_constraint(self) + + def remove_from_graph(self): + super(ScaleConstraint, self).remove_from_graph() + + if self.scale is not None: + self.scale.remove_constraint(self) + + if self.offset is not None: + self.offset.remove_constraint(self) + + def mark_inputs(self, mark): + super(ScaleConstraint, self).mark_inputs(mark) + self.scale.mark = mark + self.offset.mark = mark + + def execute(self): + if self.direction == Direction.FORWARD: + self.v2.value = self.v1.value * self.scale.value + self.offset.value + else: + self.v1.value = (self.v2.value - self.offset.value) / self.scale.value + + def recalculate(self): + ihn = self.input() + out = self.output() + out.walk_strength = Strength.weakest_of(self.strength, ihn.walk_strength) + out.stay = ihn.stay and self.scale.stay and self.offset.stay + + if out.stay: + self.execute() + + +class EqualityConstraint(BinaryConstraint): + def execute(self): + self.output().value = self.input().value + + +class Variable(object): + def __init__(self, name, initial_value=0): + super(Variable, self).__init__() + self.name = name + self.value = initial_value + self.constraints = OrderedCollection() + self.determined_by = None + self.mark = 0 + self.walk_strength = Strength.WEAKEST + self.stay = True + + def __repr__(self): + # To make debugging this beast from pdb easier... + return '' % ( + self.name, + self.value + ) + + def add_constraint(self, constraint): + self.constraints.append(constraint) + + def remove_constraint(self, constraint): + self.constraints.remove(constraint) + + if self.determined_by == constraint: + self.determined_by = None + + +class Planner(object): + def __init__(self): + super(Planner, self).__init__() + self.current_mark = 0 + + def incremental_add(self, constraint): + mark = self.new_mark() + overridden = constraint.satisfy(mark) + + while overridden is not None: + overridden = overridden.satisfy(mark) + + def incremental_remove(self, constraint): + out = constraint.output() + constraint.mark_unsatisfied() + constraint.remove_from_graph() + unsatisfied = self.remove_propagate_from(out) + strength = Strength.REQUIRED + # Do-while, the Python way. + repeat = True + + while repeat: + for u in unsatisfied: + if u.strength == strength: + self.incremental_add(u) + + strength = strength.next_weaker() + + repeat = strength != Strength.WEAKEST + + def new_mark(self): + self.current_mark += 1 + return self.current_mark + + def make_plan(self, sources): + mark = self.new_mark() + plan = Plan() + todo = sources + + while len(todo): + c = todo.pop(0) + + if c.output().mark != mark and c.inputs_known(mark): + plan.add_constraint(c) + c.output().mark = mark + self.add_constraints_consuming_to(c.output(), todo) + + return plan + + def extract_plan_from_constraints(self, constraints): + sources = OrderedCollection() + + for c in constraints: + if c.is_input() and c.is_satisfied(): + sources.append(c) + + return self.make_plan(sources) + + def add_propagate(self, c, mark): + todo = OrderedCollection() + todo.append(c) + + while len(todo): + d = todo.pop(0) + + if d.output().mark == mark: + self.incremental_remove(c) + return False + + d.recalculate() + self.add_constraints_consuming_to(d.output(), todo) + + return True + + def remove_propagate_from(self, out): + out.determined_by = None + out.walk_strength = Strength.WEAKEST + out.stay = True + unsatisfied = OrderedCollection() + todo = OrderedCollection() + todo.append(out) + + while len(todo): + v = todo.pop(0) + + for c in v.constraints: + if not c.is_satisfied(): + unsatisfied.append(c) + + determining = v.determined_by + + for c in v.constraints: + if c != determining and c.is_satisfied(): + c.recalculate() + todo.append(c.output()) + + return unsatisfied + + def add_constraints_consuming_to(self, v, coll): + determining = v.determined_by + cc = v.constraints + + for c in cc: + if c != determining and c.is_satisfied(): + # I guess we're just updating a reference (``coll``)? Seems + # inconsistent with the rest of the implementation, where they + # return the lists... + coll.append(c) + + +class Plan(object): + def __init__(self): + super(Plan, self).__init__() + self.v = OrderedCollection() + + def add_constraint(self, c): + self.v.append(c) + + def __len__(self): + return len(self.v) + + def __getitem__(self, index): + return self.v[index] + + def execute(self): + for c in self.v: + c.execute() + + +# Main + +def chain_test(n): + """ + This is the standard DeltaBlue benchmark. A long chain of equality + constraints is constructed with a stay constraint on one end. An + edit constraint is then added to the opposite end and the time is + measured for adding and removing this constraint, and extracting + and executing a constraint satisfaction plan. There are two cases. + In case 1, the added constraint is stronger than the stay + constraint and values must propagate down the entire length of the + chain. In case 2, the added constraint is weaker than the stay + constraint so it cannot be accomodated. The cost in this case is, + of course, very low. Typical situations lie somewhere between these + two extremes. + """ + global planner + planner = Planner() + prev, first, last = None, None, None + + # We need to go up to n inclusively. + for i in range(n + 1): + name = "v%s" % i + v = Variable(name) + + if prev is not None: + EqualityConstraint(prev, v, Strength.REQUIRED) + + if i == 0: + first = v + + if i == n: + last = v + + prev = v + + StayConstraint(last, Strength.STRONG_DEFAULT) + edit = EditConstraint(first, Strength.PREFERRED) + edits = OrderedCollection() + edits.append(edit) + plan = planner.extract_plan_from_constraints(edits) + + for i in range(100): + first.value = i + plan.execute() + + if last.value != i: + print("Chain test failed.") + + +def projection_test(n): + """ + This test constructs a two sets of variables related to each + other by a simple linear transformation (scale and offset). The + time is measured to change a variable on either side of the + mapping and to change the scale and offset factors. + """ + global planner + planner = Planner() + scale = Variable("scale", 10) + offset = Variable("offset", 1000) + src, dest = None, None + + dests = OrderedCollection() + + for i in range(n): + src = Variable("src%s" % i, i) + dst = Variable("dst%s" % i, i) + dests.append(dst) + StayConstraint(src, Strength.NORMAL) + ScaleConstraint(src, scale, offset, dst, Strength.REQUIRED) + + change(src, 17) + + if dst.value != 1170: + print("Projection 1 failed") + + change(dst, 1050) + + if src.value != 5: + print("Projection 2 failed") + + change(scale, 5) + + for i in range(n - 1): + if dests[i].value != (i * 5 + 1000): + print("Projection 3 failed") + + change(offset, 2000) + + for i in range(n - 1): + if dests[i].value != (i * 5 + 2000): + print("Projection 4 failed") + + +def change(v, new_value): + global planner + edit = EditConstraint(v, Strength.PREFERRED) + edits = OrderedCollection() + edits.append(edit) + + plan = planner.extract_plan_from_constraints(edits) + + for i in range(10): + v.value = new_value + plan.execute() + + edit.destroy_constraint() + + +# HOORAY FOR GLOBALS... Oh wait. +# In spirit of the original, we'll keep it, but ugh. +planner = None + + +def delta_blue(): + chain_test(100) + projection_test(100) + + +# Specific to the PyPy implementation, to run within the main harnass. +def main(n): + import time + times = [] + + for i in range(n): + t1 = time.time() + delta_blue() + t2 = time.time() + times.append(t2 - t1) + + return times + + +if __name__ == '__main__': + import util + import optparse + + parser = optparse.OptionParser( + usage="%prog [options]", + description="Test the performance of the DeltaBlue benchmark") + util.add_standard_options_to(parser) + options, args = parser.parse_args() + + util.run_benchmark(options, options.num_runs, main) From noreply at buildbot.pypy.org Tue Sep 3 11:50:41 2013 From: noreply at buildbot.pypy.org (bivab) Date: Tue, 3 Sep 2013 11:50:41 +0200 (CEST) Subject: [pypy-commit] buildbot buildbot-update: might be '' here too Message-ID: <20130903095041.0A3271C1354@cobra.cs.uni-duesseldorf.de> Author: David Schneider Branch: buildbot-update Changeset: r845:26e384bdd696 Date: 2013-08-30 16:21 +0200 http://bitbucket.org/pypy/buildbot/changeset/26e384bdd696/ Log: might be '' here too diff --git a/bot2/pypybuildbot/builds.py b/bot2/pypybuildbot/builds.py --- a/bot2/pypybuildbot/builds.py +++ b/bot2/pypybuildbot/builds.py @@ -89,7 +89,7 @@ if branch.startswith('/'): branch = branch[1:] mastersrc = os.path.join(mastersrc, branch) - if revision is not None: + if revision: basename = WithProperties(self.basename).getRenderingFor(self.build) basename = basename.replace(':', '-') else: From noreply at buildbot.pypy.org Tue Sep 3 11:50:43 2013 From: noreply at buildbot.pypy.org (bivab) Date: Tue, 3 Sep 2013 11:50:43 +0200 (CEST) Subject: [pypy-commit] buildbot buildbot-update: add haltOnFailure to some ShellCmd instances Message-ID: <20130903095043.3ED971C138A@cobra.cs.uni-duesseldorf.de> Author: David Schneider Branch: buildbot-update Changeset: r847:974cf627bd32 Date: 2013-08-30 16:32 +0200 http://bitbucket.org/pypy/buildbot/changeset/974cf627bd32/ Log: add haltOnFailure to some ShellCmd instances diff --git a/bot2/pypybuildbot/builds.py b/bot2/pypybuildbot/builds.py --- a/bot2/pypybuildbot/builds.py +++ b/bot2/pypybuildbot/builds.py @@ -390,22 +390,27 @@ self.addStep(ShellCmd( description="decompress pypy-c", command=['tar', '--extract', '--file=pypy_build'+ extension, '--strip-components=1', '--directory=.'], - workdir='pypy-c')) + workdir='pypy-c', + haltOnFailure=True, + )) # copy pypy-c to the expected location within the pypy source checkout self.addStep(ShellCmd( description="move pypy-c", command=['cp', '-v', 'pypy-c/bin/pypy', 'build/pypy/goal/pypy-c'], + haltOnFailure=True, workdir='.')) # copy generated and copied header files to build/include self.addStep(ShellCmd( description="move header files", command=['cp', '-vr', 'pypy-c/include', 'build'], + haltOnFailure=True, workdir='.')) # copy ctypes_resource_cache generated during translation self.addStep(ShellCmd( description="move ctypes resource cache", command=['cp', '-rv', 'pypy-c/lib_pypy/ctypes_config_cache', 'build/lib_pypy'], + haltOnFailure=True, workdir='.')) add_translated_tests(self, prefix, platform, app_tests, lib_python, pypyjit) @@ -430,6 +435,7 @@ command=prefix + ["python", "pypy/tool/release/package.py", ".", WithProperties(name), 'pypy', '.'], + haltOnFailure=True, workdir='build')) nightly = '~/nightly/' extension = get_extension(platform) From noreply at buildbot.pypy.org Tue Sep 3 11:50:42 2013 From: noreply at buildbot.pypy.org (bivab) Date: Tue, 3 Sep 2013 11:50:42 +0200 (CEST) Subject: [pypy-commit] buildbot buildbot-update: create a buildfactory to run buildbot tests Message-ID: <20130903095042.1AF711C1360@cobra.cs.uni-duesseldorf.de> Author: David Schneider Branch: buildbot-update Changeset: r846:161df5e0980e Date: 2013-08-30 16:23 +0200 http://bitbucket.org/pypy/buildbot/changeset/161df5e0980e/ Log: create a buildfactory to run buildbot tests diff --git a/bot2/pypybuildbot/builds.py b/bot2/pypybuildbot/builds.py --- a/bot2/pypybuildbot/builds.py +++ b/bot2/pypybuildbot/builds.py @@ -587,3 +587,35 @@ self.addStep(transfer.FileUpload(slavesrc="benchmarks/result.json", masterdest=WithProperties(resultfile), workdir=".")) + +class PyPyBuildbotTestFactory(factory.BuildFactory): + def __init__(self): + factory.BuildFactory.__init__(self) + # clone + self.addStep( + Mercurial( + repourl='https://bitbucket.org/pypy/buildbot', + mode='incremental', + method='fresh', + defaultBranch='default', + branchType='inrepo', + clobberOnBranchChange=False, + logEnviron=False)) + # create a virtualenv + self.addStep(ShellCmd( + description='create virtualenv', + haltOnFailure=True, + command='virtualenv ../venv')) + # install deps + self.addStep(ShellCmd( + description="install dependencies", + haltOnFailure=True, + command=('../venv/bin/pip install -r requirements.txt').split())) + # run tests + self.addStep(PytestCmd( + description="pytest buildbot", + haltOnFailure=True, + command=["../venv/bin/py.test", + "--resultlog=testrun.log", + ], + logfiles={'pytestLog': 'testrun.log'})) From noreply at buildbot.pypy.org Tue Sep 3 11:50:44 2013 From: noreply at buildbot.pypy.org (bivab) Date: Tue, 3 Sep 2013 11:50:44 +0200 (CEST) Subject: [pypy-commit] buildbot buildbot-update: update docs Message-ID: <20130903095044.569DF1C138B@cobra.cs.uni-duesseldorf.de> Author: David Schneider Branch: buildbot-update Changeset: r848:db29eedae873 Date: 2013-09-03 11:50 +0200 http://bitbucket.org/pypy/buildbot/changeset/db29eedae873/ Log: update docs diff --git a/README b/README --- a/README +++ b/README @@ -1,7 +1,6 @@ .. -*- mode: rst -*- -Everything has been tested with builbot 0.7.12. Not sure what happens with -other versions :-) +Everything has been tested with builbot 0.8.8. How to hack the PyPy buildbot ============================== @@ -24,12 +23,12 @@ If you want to run buildbot in production, you need to make sure that the function ``pypybuildbot.util.we_are_debugging`` returns ``False`` in your environment. At the moment of writing, debugging is enabled everywhere but on -wyvern. +cobra. You still need to fill ``master/slaveinfo.py`` with the passwords of the various slaves you want to use. -Then, to start the buildbot master: ``cd master; make start`` +Then, to start the buildbot master: ``buildbot start `` To restart the buildmaster @@ -43,13 +42,13 @@ $ buildbot checkconfig -$ make reconfig +$ buildbot reconfig OR -$ make stop +$ buildbot stop -$ make start +$ buildbot start To run a buildslave =================== diff --git a/bot2/pypybuildbot/util.py b/bot2/pypybuildbot/util.py --- a/bot2/pypybuildbot/util.py +++ b/bot2/pypybuildbot/util.py @@ -2,7 +2,7 @@ import socket def we_are_debugging(): - return socket.gethostname() not in ("wyvern", "cobra") + return socket.gethostname() != 'cobra' def load(name): mod = __import__(name, {}, {}, ['__all__']) From noreply at buildbot.pypy.org Tue Sep 3 11:50:39 2013 From: noreply at buildbot.pypy.org (bivab) Date: Tue, 3 Sep 2013 11:50:39 +0200 (CEST) Subject: [pypy-commit] buildbot buildbot-update: map several possible values to 'trunk' for the downloads page Message-ID: <20130903095039.C9AB11C0270@cobra.cs.uni-duesseldorf.de> Author: David Schneider Branch: buildbot-update Changeset: r844:f8dca433431b Date: 2013-08-30 16:18 +0200 http://bitbucket.org/pypy/buildbot/changeset/f8dca433431b/ Log: map several possible values to 'trunk' for the downloads page diff --git a/bot2/pypybuildbot/builds.py b/bot2/pypybuildbot/builds.py --- a/bot2/pypybuildbot/builds.py +++ b/bot2/pypybuildbot/builds.py @@ -28,6 +28,7 @@ # while the boards can only run one job at the same time ARMBoardLock = locks.SlaveLock('arm_boards', maxCount=1) +map_branch_name = lambda x: x if x not in ['', None, 'default'] else 'trunk' class ShellCmd(shell.ShellCommand): # our own version that can distinguish abort cases (rc == -1) @@ -44,9 +45,7 @@ def start(self): properties = self.build.getProperties() - branch = properties['branch'] - if branch is None: - branch = 'trunk' + branch = map_branch_name(properties['branch']) #masterdest = properties.render(self.masterdest) masterdest = os.path.expanduser(self.masterdest) if branch.startswith('/'): @@ -83,11 +82,8 @@ def start(self): properties = self.build.getProperties() - branch = properties['branch'] + branch = map_branch_name(properties['branch']) revision = properties['revision'] - - if branch is None: - branch = 'trunk' mastersrc = os.path.expanduser(self.mastersrc) if branch.startswith('/'): @@ -158,9 +154,7 @@ builder.summary_by_branch_and_revision = {} try: rev = properties['got_revision'] - branch = properties['branch'] - if branch is None: - branch = 'trunk' + branch = map_branch_name(properties['branch']) if branch.endswith('/'): branch = branch[:-1] except KeyError: From noreply at buildbot.pypy.org Tue Sep 3 13:35:10 2013 From: noreply at buildbot.pypy.org (bivab) Date: Tue, 3 Sep 2013 13:35:10 +0200 (CEST) Subject: [pypy-commit] buildbot buildbot-update: keep trunk as meta-branch that groups default and builds without an explicit branch Message-ID: <20130903113510.8FDF51C135D@cobra.cs.uni-duesseldorf.de> Author: David Schneider Branch: buildbot-update Changeset: r849:3781586166f4 Date: 2013-09-03 13:34 +0200 http://bitbucket.org/pypy/buildbot/changeset/3781586166f4/ Log: keep trunk as meta-branch that groups default and builds without an explicit branch diff --git a/bot2/pypybuildbot/summary.py b/bot2/pypybuildbot/summary.py --- a/bot2/pypybuildbot/summary.py +++ b/bot2/pypybuildbot/summary.py @@ -624,10 +624,10 @@ return subst # Map certain branch names from SourceStamps to a common name shown on the page -meta_branch_name = make_subst(['default', '', None], '') -# map the meta-branch to the actual branch entries from the +meta_branch_name = make_subst(['default', '', None], '') +# map the meta-branch to the actual branch entries from the # SourceStamp -default_value = make_subst('', ['default', '', None]) +default_value = make_subst('', ['default', '', None]) category_name = make_subst(None, '-') nocat_value = make_subst("-", None) @@ -876,8 +876,8 @@ default_vs_any_text = "filter nothing" default_vs_any_query = "" else: - default_vs_any_text = "all " - default_vs_any_query = "?branch=" + default_vs_any_text = "all " + default_vs_any_query = "?branch=" default_vs_any_anchor = html.a(default_vs_any_text, href="/summary%s" % diff --git a/bot2/pypybuildbot/test/test_summary.py b/bot2/pypybuildbot/test/test_summary.py --- a/bot2/pypybuildbot/test/test_summary.py +++ b/bot2/pypybuildbot/test/test_summary.py @@ -482,7 +482,7 @@ builder.nextBuildNumber = n -METABRANCH = '' +METABRANCH = '' class TestSummary(object): diff --git a/master/templates/layout.html b/master/templates/layout.html --- a/master/templates/layout.html +++ b/master/templates/layout.html @@ -26,7 +26,7 @@ - Speed - Summary (default) + Summary (trunk) Summary Nightly builds From noreply at buildbot.pypy.org Tue Sep 3 14:55:09 2013 From: noreply at buildbot.pypy.org (bivab) Date: Tue, 3 Sep 2013 14:55:09 +0200 (CEST) Subject: [pypy-commit] buildbot default: merge buildbot-update branch, this updates buildbot to 0.8.8 Message-ID: <20130903125509.254801D1F53@cobra.cs.uni-duesseldorf.de> Author: David Schneider Branch: Changeset: r850:7c9ad7d03687 Date: 2013-09-03 14:54 +0200 http://bitbucket.org/pypy/buildbot/changeset/7c9ad7d03687/ Log: merge buildbot-update branch, this updates buildbot to 0.8.8 diff too long, truncating to 2000 out of 2180 lines diff --git a/README b/README --- a/README +++ b/README @@ -1,7 +1,6 @@ .. -*- mode: rst -*- -Everything has been tested with builbot 0.7.12. Not sure what happens with -other versions :-) +Everything has been tested with builbot 0.8.8. How to hack the PyPy buildbot ============================== @@ -24,12 +23,12 @@ If you want to run buildbot in production, you need to make sure that the function ``pypybuildbot.util.we_are_debugging`` returns ``False`` in your environment. At the moment of writing, debugging is enabled everywhere but on -wyvern. +cobra. You still need to fill ``master/slaveinfo.py`` with the passwords of the various slaves you want to use. -Then, to start the buildbot master: ``cd master; make start`` +Then, to start the buildbot master: ``buildbot start `` To restart the buildmaster @@ -43,13 +42,13 @@ $ buildbot checkconfig -$ make reconfig +$ buildbot reconfig OR -$ make stop +$ buildbot stop -$ make start +$ buildbot start To run a buildslave =================== diff --git a/bot2/pypybuildbot/arm_master.py b/bot2/pypybuildbot/arm_master.py --- a/bot2/pypybuildbot/arm_master.py +++ b/bot2/pypybuildbot/arm_master.py @@ -120,6 +120,21 @@ BUILDJITLINUXARMHF_RASPBIAN = "build-pypy-c-jit-linux-armhf-raspbian" BUILDJITLINUXARMHF_RARING = "build-pypy-c-jit-linux-armhf-raring" +builderNames = [ + APPLVLLINUXARM, + APPLVLLINUXARMHF_v7, + APPLVLLINUXARMHF_RASPBIAN, + JITLINUXARM, + JITLINUXARMHF_v7, + JITLINUXARMHF_RASPBIAN, + JITBACKENDONLYLINUXARMEL, + JITBACKENDONLYLINUXARMHF, + JITBACKENDONLYLINUXARMHF_v7, + BUILDLINUXARM, + BUILDJITLINUXARM, + BUILDLINUXARMHF_RASPBIAN, + BUILDJITLINUXARMHF_RASPBIAN, +] schedulers = [ Nightly("nighly-arm-0-00", [ diff --git a/bot2/pypybuildbot/builds.py b/bot2/pypybuildbot/builds.py --- a/bot2/pypybuildbot/builds.py +++ b/bot2/pypybuildbot/builds.py @@ -1,3 +1,4 @@ +from buildbot.steps.source.mercurial import Mercurial from buildbot.process import factory from buildbot.steps import shell, transfer from buildbot.steps.trigger import Trigger @@ -27,10 +28,7 @@ # while the boards can only run one job at the same time ARMBoardLock = locks.SlaveLock('arm_boards', maxCount=1) - -# XXX monkey patch Trigger class, there are to issues with the list of renderables -# original: Trigger.renderables = [ 'set_propetries', 'scheduler', 'sourceStamp' ] -Trigger.renderables = [ 'set_properties', 'schedulerNames', 'sourceStamp' ] +map_branch_name = lambda x: x if x not in ['', None, 'default'] else 'trunk' class ShellCmd(shell.ShellCommand): # our own version that can distinguish abort cases (rc == -1) @@ -47,9 +45,7 @@ def start(self): properties = self.build.getProperties() - branch = properties['branch'] - if branch is None: - branch = 'trunk' + branch = map_branch_name(properties['branch']) #masterdest = properties.render(self.masterdest) masterdest = os.path.expanduser(self.masterdest) if branch.startswith('/'): @@ -59,8 +55,8 @@ if not os.path.exists(masterdest): os.makedirs(masterdest) # - assert '%(final_file_name)s' in self.basename - symname = self.basename.replace('%(final_file_name)s', 'latest') + assert '%(got_revision)s' in self.basename + symname = self.basename.replace('%(got_revision)s', 'latest') assert '%' not in symname self.symlinkname = os.path.join(masterdest, symname) # @@ -86,17 +82,14 @@ def start(self): properties = self.build.getProperties() - branch = properties['branch'] + branch = map_branch_name(properties['branch']) revision = properties['revision'] - - if branch is None: - branch = 'trunk' mastersrc = os.path.expanduser(self.mastersrc) if branch.startswith('/'): branch = branch[1:] mastersrc = os.path.join(mastersrc, branch) - if revision is not None: + if revision: basename = WithProperties(self.basename).getRenderingFor(self.build) basename = basename.replace(':', '-') else: @@ -161,9 +154,7 @@ builder.summary_by_branch_and_revision = {} try: rev = properties['got_revision'] - branch = properties['branch'] - if branch is None: - branch = 'trunk' + branch = map_branch_name(properties['branch']) if branch.endswith('/'): branch = branch[:-1] except KeyError: @@ -178,92 +169,18 @@ # _______________________________________________________________ -class UpdateCheckout(ShellCmd): - description = 'hg update' - command = 'UNKNOWN' - - def __init__(self, workdir=None, haltOnFailure=True, force_branch=None, - **kwargs): - ShellCmd.__init__(self, workdir=workdir, haltOnFailure=haltOnFailure, - **kwargs) - self.force_branch = force_branch - self.addFactoryArguments(force_branch=force_branch) - - def start(self): - if self.force_branch is not None: - branch = self.force_branch - # Note: We could add a warning to the output if we - # ignore the branch set by the user. - else: - properties = self.build.getProperties() - branch = properties['branch'] or 'default' - command = ["hg", "update", "--clean", "-r", branch] - self.setCommand(command) - ShellCmd.start(self) - - -class CheckGotRevision(ShellCmd): - description = 'got_revision' - command = ['hg', 'parents', '--template', 'got_revision:{rev}:{node}'] - - def commandComplete(self, cmd): - if cmd.rc == 0: - got_revision = cmd.logs['stdio'].getText() - got_revision = got_revision.split('got_revision:')[-1] - # manually get the effect of {node|short} without using a - # '|' in the command-line, because it doesn't work on Windows - num = got_revision.find(':') - if num > 0: - got_revision = got_revision[:num + 13] - # - final_file_name = got_revision.replace(':', '-') - # ':' should not be part of filenames --- too many issues - self.build.setProperty('got_revision', got_revision, - 'got_revision') - self.build.setProperty('final_file_name', final_file_name, - 'got_revision') - - def update_hg(platform, factory, repourl, workdir, use_branch, force_branch=None): - if platform == 'win32': - command = "if not exist .hg rmdir /q /s ." - else: - command = "if [ ! -d .hg ]; then rm -fr * .[a-z]*; fi" - factory.addStep(ShellCmd(description="rmdir?", - command=command, - workdir=workdir, - haltOnFailure=False)) - # - if platform == "win32": - command = "if not exist .hg %s" - else: - command = "if [ ! -d .hg ]; then %s; fi" - command = command % ("hg clone -U " + repourl + " .") - factory.addStep(ShellCmd(description="hg clone", - command=command, - workdir=workdir, - timeout=3600, - haltOnFailure=True)) - # factory.addStep( - ShellCmd(description="hg purge", - command="hg --config extensions.purge= purge --all", - workdir=workdir, - haltOnFailure=True)) - # - factory.addStep(ShellCmd(description="hg pull", - command="hg pull", - workdir=workdir)) - # - if use_branch or force_branch: - factory.addStep(UpdateCheckout(workdir=workdir, - haltOnFailure=True, - force_branch=force_branch)) - else: - factory.addStep(ShellCmd(description="hg update", - command=WithProperties("hg update --clean %(revision)s"), - workdir=workdir)) + Mercurial( + repourl=repourl, + mode='incremental', + method='fresh', + defaultBranch=force_branch, + branchType='inrepo', + clobberOnBranchChange=False, + workdir=workdir, + logEnviron=False)) def setup_steps(platform, factory, workdir=None, @@ -278,11 +195,11 @@ update_hg(platform, factory, repourl, workdir, use_branch=True, force_branch=force_branch) # - factory.addStep(CheckGotRevision(workdir=workdir)) + def build_name(platform, jit=False, flags=[], placeholder=None): if placeholder is None: - placeholder = '%(final_file_name)s' + placeholder = '%(got_revision)s' if jit or '-Ojit' in flags: kind = 'jit' else: @@ -473,22 +390,27 @@ self.addStep(ShellCmd( description="decompress pypy-c", command=['tar', '--extract', '--file=pypy_build'+ extension, '--strip-components=1', '--directory=.'], - workdir='pypy-c')) + workdir='pypy-c', + haltOnFailure=True, + )) # copy pypy-c to the expected location within the pypy source checkout self.addStep(ShellCmd( description="move pypy-c", command=['cp', '-v', 'pypy-c/bin/pypy', 'build/pypy/goal/pypy-c'], + haltOnFailure=True, workdir='.')) # copy generated and copied header files to build/include self.addStep(ShellCmd( description="move header files", command=['cp', '-vr', 'pypy-c/include', 'build'], + haltOnFailure=True, workdir='.')) # copy ctypes_resource_cache generated during translation self.addStep(ShellCmd( description="move ctypes resource cache", command=['cp', '-rv', 'pypy-c/lib_pypy/ctypes_config_cache', 'build/lib_pypy'], + haltOnFailure=True, workdir='.')) add_translated_tests(self, prefix, platform, app_tests, lib_python, pypyjit) @@ -513,6 +435,7 @@ command=prefix + ["python", "pypy/tool/release/package.py", ".", WithProperties(name), 'pypy', '.'], + haltOnFailure=True, workdir='build')) nightly = '~/nightly/' extension = get_extension(platform) @@ -670,3 +593,35 @@ self.addStep(transfer.FileUpload(slavesrc="benchmarks/result.json", masterdest=WithProperties(resultfile), workdir=".")) + +class PyPyBuildbotTestFactory(factory.BuildFactory): + def __init__(self): + factory.BuildFactory.__init__(self) + # clone + self.addStep( + Mercurial( + repourl='https://bitbucket.org/pypy/buildbot', + mode='incremental', + method='fresh', + defaultBranch='default', + branchType='inrepo', + clobberOnBranchChange=False, + logEnviron=False)) + # create a virtualenv + self.addStep(ShellCmd( + description='create virtualenv', + haltOnFailure=True, + command='virtualenv ../venv')) + # install deps + self.addStep(ShellCmd( + description="install dependencies", + haltOnFailure=True, + command=('../venv/bin/pip install -r requirements.txt').split())) + # run tests + self.addStep(PytestCmd( + description="pytest buildbot", + haltOnFailure=True, + command=["../venv/bin/py.test", + "--resultlog=testrun.log", + ], + logfiles={'pytestLog': 'testrun.log'})) diff --git a/bot2/pypybuildbot/ircbot.py b/bot2/pypybuildbot/ircbot.py --- a/bot2/pypybuildbot/ircbot.py +++ b/bot2/pypybuildbot/ircbot.py @@ -7,54 +7,64 @@ the customized IRC messages. """ -import re -from buildbot.status.words import Contact, IRC, log +from buildbot.status.words import IRC, log, IRCContact +# see http://www.mirc.com/colors.html USE_COLOR_CODES = True -GREEN = '\x033' -RED = '\x034' -AZURE = '\x0311' -BLUE = '\x0312' -PURPLE = '\x0313' -GRAY = '\x0315' -BOLD = '\x02' -def color(code, s): +BOLD = '\x02' +COLORS = { + 'WHITE': '\x030', + 'BLACK': '\x031', + 'GREEN': '\x033', + 'RED': '\x034', + 'AZURE': '\x0311', + 'BLUE': '\x0312', + 'PURPLE': '\x0313', + 'GRAY': '\x0315', +} + + +def color(s, code=None, bold=False): if USE_COLOR_CODES: - return '%s%s\x0F' % (code, s) + c = BOLD if bold else '' + if code in COLORS: + c += COLORS[code] + return '%s%s\x0F' % (c, s) return s -def extract_username(build): - regexp = r"The web-page 'force build' button was pressed by '(.*)': .*" - match = re.match(regexp, build.getReason()) - if match: - return match.group(1) - return None + +def get_build_information(build): + owner = build.getProperty("owner") + reason = build.getProperty("reason") + return ": ".join(k for k in (owner, reason) if k) def get_description_for_build(url, build): - url = color(GRAY, url) # in gray + url = color(url, 'GRAY') # in gray infos = [] - username = extract_username(build) - if username: - infos.append(color(BLUE, username)) # in blue + buildinfo = get_build_information(build) + if buildinfo: + infos.append(color(buildinfo, 'BLUE')) # in blue # - branch = build.source.branch + branch = build.getProperty('branch') if branch: - infos.append(color(BOLD, branch)) # in bold + infos.append(color(branch, bold=True)) # in bold # if infos: return '%s [%s]' % (url, ', '.join(infos)) else: return url + def buildStarted(self, builderName, build): builder = build.getBuilder() - log.msg('[Contact] Builder %r in category %s started' % (builder, builder.category)) + log.msg('[Contact] Builder %r in category %s started' % + (builder, builder.category)) # only notify about builders we are interested in - if (self.channel.categories != None and - builder.category not in self.channel.categories): + if (self.bot.categories is not None and + builder.category not in self.bot.categories): log.msg('Not notifying for a build in the wrong category') return @@ -62,7 +72,7 @@ log.msg('Not notifying for a build when started-notification disabled') return - buildurl = self.channel.status.getURLForThing(build) + buildurl = self.bot.status.getURLForThing(build) descr = get_description_for_build(buildurl, build) msg = "Started: %s" % descr self.send(msg) @@ -72,29 +82,28 @@ builder = build.getBuilder() # only notify about builders we are interested in - log.msg('[Contact] builder %r in category %s finished' % (builder, builder.category)) + log.msg('[Contact] builder %r in category %s finished' % + (builder, builder.category)) - if (self.channel.categories != None and - builder.category not in self.channel.categories): + if (self.bot.categories is not None and + builder.category not in self.bot.categories): return if not self.notify_for_finished(build): return - buildurl = self.channel.status.getURLForThing(build) + buildurl = self.bot.status.getURLForThing(build) descr = get_description_for_build(buildurl, build) - result = self.results_descriptions.get(build.getResults(), "Finished ??") - if result == 'Success': - result = color(BOLD+GREEN, result) - elif result == 'Exception': - result = color(BOLD+PURPLE, result) - else: - result = color(BOLD+RED, result) + result, c = self.results_descriptions.get(build.getResults(), + ("Finished ??", 'RED')) + if c not in COLORS: + c = 'RED' + result = color(result, c, bold=True) msg = "%s: %s" % (result, descr) self.send(msg) -Contact.buildStarted = buildStarted -Contact.buildFinished = buildFinished +IRCContact.buildStarted = buildStarted +IRCContact.buildFinished = buildFinished ## def send_message(message, test=False): diff --git a/bot2/pypybuildbot/master.py b/bot2/pypybuildbot/master.py --- a/bot2/pypybuildbot/master.py +++ b/bot2/pypybuildbot/master.py @@ -1,25 +1,22 @@ import os -import getpass -from buildbot.scheduler import Nightly, Triggerable +from buildbot.scheduler import Nightly +from buildbot.schedulers.forcesched import ForceScheduler +from buildbot.schedulers.forcesched import ValidationError from buildbot.buildslave import BuildSlave from buildbot.status.html import WebStatus -from buildbot.process.builder import Builder #from buildbot import manhole from pypybuildbot.pypylist import PyPyList, NumpyStatusList -from pypybuildbot.ircbot import IRC # side effects +from pypybuildbot.ircbot import IRC # side effects from pypybuildbot.util import we_are_debugging # Forbid "force build" with empty user name -from buildbot.status.web.builder import StatusResourceBuilder -def my_force(self, req, *args, **kwds): - name = req.args.get("username", [""])[0] - assert name, "Please write your name in the corresponding field." - return _previous_force(self, req, *args, **kwds) -_previous_force = StatusResourceBuilder.force -if _previous_force.__name__ == 'force': - StatusResourceBuilder.force = my_force -# Done +class CustomForceScheduler(ForceScheduler): + def force(self, owner, builder_name, **kwargs): + if not owner: + raise ValidationError, "Please write your name in the corresponding field." + return ForceScheduler.force(self, owner, builder_name, **kwargs) + if we_are_debugging(): channel = '#buildbot-test' @@ -216,12 +213,12 @@ JITFREEBSD864, # on ananke JITFREEBSD964, # on exarkun's freebsd JITMACOSX64, # on xerxes - ], branch=None, hour=0, minute=0), + ], branch='default', hour=0, minute=0), 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=2, minute=0), + ], branch='default', hour=2, minute=0), Nightly("nightly-2-00-py3k", [ LINUX64, # on allegro64, uses all cores @@ -231,6 +228,36 @@ Nightly("nighly-ppc", [ JITONLYLINUXPPC64, # on gcc1 ], branch='ppc-jit-backend', hour=1, minute=0), + CustomForceScheduler('Force Scheduler', + builderNames=[ + LINUX32, + LINUX64, + INDIANA32, + + MACOSX32, + WIN32, + WIN64, + APPLVLLINUX32, + APPLVLLINUX64, + APPLVLWIN32, + + LIBPYTHON_LINUX32, + LIBPYTHON_LINUX64, + + JITLINUX32, + JITLINUX64, + JITMACOSX64, + JITWIN32, + JITWIN64, + JITFREEBSD764, + JITFREEBSD864, + JITFREEBSD964, + JITINDIANA32, + + JITONLYLINUXPPC64, + JITBENCH, + JITBENCH64, + ] + ARM.builderNames, properties=[]), ] + ARM.schedulers, 'status': [status, ircbot], diff --git a/bot2/pypybuildbot/summary.py b/bot2/pypybuildbot/summary.py --- a/bot2/pypybuildbot/summary.py +++ b/bot2/pypybuildbot/summary.py @@ -374,7 +374,7 @@ def _start_cat_branch(self, cat_branch, fine=False): category, branch = cat_branch - branch = trunk_name(branch) + branch = meta_branch_name(branch) category = category_name(category) self.cur_cat_branch = (category, branch) @@ -615,14 +615,19 @@ return lambda v: v in membs def make_subst(v1, v2): + if not isinstance(v1, list): + v1 = [v1] def subst(v): - if v == v1: + if v in v1: return v2 return v return subst -trunk_name = make_subst(None, "") -trunk_value = make_subst("", None) +# Map certain branch names from SourceStamps to a common name shown on the page +meta_branch_name = make_subst(['default', '', None], '') +# map the meta-branch to the actual branch entries from the +# SourceStamp +default_value = make_subst('', ['default', '', None]) category_name = make_subst(None, '-') nocat_value = make_subst("-", None) @@ -661,8 +666,7 @@ def getTitle(self, request): status = self.getStatus(request) - return "%s: summaries of last %d revisions" % (status.getProjectName(), - N) + return "%s: summaries of last %d revisions" % (status.getTitle(), N) @staticmethod def _prune_runs(runs, cutnum): @@ -686,8 +690,10 @@ except KeyError: pass builder = status.botmaster.builders[builderName] + factory = builder.config.factory branch = None - for _, kw in builder.buildFactory.steps: + for step in factory.steps: + kw = step.kwargs if 'defaultBranch' in kw: if kw.get('explicitBranch'): branch = kw['defaultBranch'] @@ -722,7 +728,6 @@ only_builder or only_branches) cat_branches = {} - for builderName in status.getBuilderNames(only_categories): if not test_builder(builderName): continue @@ -747,6 +752,7 @@ if not test_rev(got_rev): continue + branch = meta_branch_name(branch) cat_branch = (builderStatus.category, branch) runs, no_revision_builds = cat_branches.setdefault(cat_branch, @@ -825,7 +831,13 @@ only_branches = request.args.get('branch', None) only_recentrevs = request.args.get('recentrev', None) if only_branches is not None: - only_branches = map(trunk_value, only_branches) + branches = [] + for x in map(default_value, only_branches): + if isinstance(x, str): + branches.append(x) + else: + branches.extend(x) + only_branches = branches only_builder = request.args.get('builder', None) only_builds = None if only_builder is not None: @@ -861,16 +873,16 @@ outcome_set_cache.stats())) if request.args: - trunk_vs_any_text = "filter nothing" - trunk_vs_any_query = "" + default_vs_any_text = "filter nothing" + default_vs_any_query = "" else: - trunk_vs_any_text = "all " - trunk_vs_any_query = "?branch=" + default_vs_any_text = "all " + default_vs_any_query = "?branch=" - trunk_vs_any_anchor = html.a(trunk_vs_any_text, + default_vs_any_anchor = html.a(default_vs_any_text, href="/summary%s" % - trunk_vs_any_query, + default_vs_any_query, class_="failSummary trunkVsAny") - trunk_vs_any = html.div(trunk_vs_any_anchor, + default_vs_any = html.div(default_vs_any_anchor, style="position: absolute; right: 5%;") - return trunk_vs_any.unicode() + page.render() + return default_vs_any.unicode() + page.render() diff --git a/bot2/pypybuildbot/test/test_builds.py b/bot2/pypybuildbot/test/test_builds.py --- a/bot2/pypybuildbot/test/test_builds.py +++ b/bot2/pypybuildbot/test/test_builds.py @@ -5,8 +5,7 @@ class FakeProperties(object): def __init__(self): - from buildbot.process.properties import PropertyMap - self.pmap = PropertyMap(self) + pass def __getitem__(self, item): if item == 'branch': @@ -42,15 +41,16 @@ return FakeDeferred() def test_Translate(): - expected = ['translate.py', '--batch', '-O0', + expected = ['pypy', '../../rpython/bin/rpython', '--batch', '-O0', 'targetpypystandalone', '--no-allworkingmodules'] translateInst = builds.Translate(['-O0'], ['--no-allworkingmodules']) assert translateInst.command[-len(expected):] == expected - translateFactory, kw = translateInst.factory - rebuiltTranslate = translateFactory(**kw) + translateFactory = translateInst._getStepFactory().factory + args = translateInst._getStepFactory().args + rebuiltTranslate = translateFactory(*args) assert rebuiltTranslate.command[-len(expected):] == expected @@ -62,9 +62,10 @@ def test_pypy_upload(): pth = py.test.ensuretemp('buildbot') inst = builds.PyPyUpload(slavesrc='slavesrc', masterdest=str(pth.join('mstr')), - basename='base-%(final_file_name)s', workdir='.', + basename='base-%(got_revision)s', workdir='.', blocksize=100) - factory, kw = inst.factory + factory = inst._getStepFactory().factory + kw = inst._getStepFactory().kwargs rebuilt = factory(**kw) rebuilt.build = FakeBuild() rebuilt.step_status = FakeStepStatus() @@ -72,7 +73,7 @@ rebuilt.start() assert pth.join('mstr').check(dir=True) assert rebuilt.masterdest == str(pth.join('mstr', 'trunk', - 'base-123-ea5ca8')) + 'base-123')) assert rebuilt.symlinkname == str(pth.join('mstr', 'trunk', 'base-latest')) diff --git a/bot2/pypybuildbot/test/test_ircbot.py b/bot2/pypybuildbot/test/test_ircbot.py --- a/bot2/pypybuildbot/test/test_ircbot.py +++ b/bot2/pypybuildbot/test/test_ircbot.py @@ -1,50 +1,48 @@ from pypybuildbot import ircbot + def setup_module(mod): ircbot.USE_COLOR_CODES = False + def teardown_module(mod): ircbot.USE_COLOR_CODES = True + class FakeBuild(object): - def __init__(self, reason=None, source=None): - self.reason = reason - self.source = source + def __init__(self, reason=None, owner=None, branch=None): + self.properties = {'owner': owner, 'branch': branch, 'reason': reason} - def getReason(self): - return self.reason + def getProperty(self, name): + return self.properties.get(name, None) - def getSourceStamp(self): - return self.source -class FakeSource(object): - - def __init__(self, branch): - self.branch = branch - -def test_extract_username(): - a = FakeBuild("The web-page 'force build' button was pressed by 'antocuni': foo") +def test_get_build_information(): + a = FakeBuild(owner='antocuni', + reason="The web-page 'force build' button was pressed") b = FakeBuild("The web-page 'force build' button was ...") - assert ircbot.extract_username(a) == 'antocuni' - assert ircbot.extract_username(b) is None + assert ircbot.get_build_information(a) == \ + "antocuni: The web-page 'force build' button was pressed" + assert ircbot.get_build_information(b) == \ + "The web-page 'force build' button was ..." def test_get_description_for_build(): - a = FakeBuild('foobar', source=FakeSource(None)) + a = FakeBuild() msg = ircbot.get_description_for_build("http://myurl", a) assert msg == "http://myurl" - a = FakeBuild("The web-page 'force build' button was pressed by 'antocuni': foo", - source=FakeSource(None)) + a = FakeBuild(owner='antocuni', + reason="The web-page 'force build' button was pressed") msg = ircbot.get_description_for_build("http://myurl", a) - assert msg == "http://myurl [antocuni]" + assert msg == "http://myurl [antocuni: " \ + + "The web-page 'force build' button was pressed]" - a = FakeBuild('foobar', source=FakeSource('mybranch')) + a = FakeBuild(branch='mybranch') msg = ircbot.get_description_for_build("http://myurl", a) assert msg == "http://myurl [mybranch]" - a = FakeBuild("The web-page 'force build' button was pressed by 'antocuni': foo", - source=FakeSource('mybranch')) + a = FakeBuild(owner='antocuni', branch='mybranch') msg = ircbot.get_description_for_build("http://myurl", a) assert msg == "http://myurl [antocuni, mybranch]" 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 @@ -78,18 +78,20 @@ newdir.setmtime(oldtime + ascii * 10) pypylist = PyPyList(tmpdir.strpath) listener = pypylist.directoryListing() - assert listener.dirs == ['trunk', 'mmmm', 'llll', + assert listener.dirs == ['trunk', 'llll', 'kkkk','jjjj','iiii','hhhh','gggg','ffff','eeee', 'dddd','cccc','bbbb','aaaa'] def load_BuildmasterConfig(): import os - from pypybuildbot import summary, builds + from pypybuildbot import summary, builds, arm_master def load(name): if name == 'pypybuildbot.summary': return summary elif name == 'pypybuildbot.builds': return builds + elif name == 'pypybuildbot.arm_master': + return arm_master else: assert False diff --git a/bot2/pypybuildbot/test/test_summary.py b/bot2/pypybuildbot/test/test_summary.py --- a/bot2/pypybuildbot/test/test_summary.py +++ b/bot2/pypybuildbot/test/test_summary.py @@ -27,7 +27,7 @@ s a/b.py:test_three S a/c.py:test_four """) - + rev_outcome_set.populate(log) assert rev_outcome_set.skipped == set([("a.b","test_three"), @@ -67,7 +67,7 @@ x a/c.py:test_nine x a/c.py:test_ten """) - + rev_outcome_set.populate(log) sum = rev_outcome_set.get_summary() assert sum.p == 1 @@ -80,7 +80,7 @@ rev_outcome_set = summary.RevisionOutcomeSet('0') log = StringIO("") rev_outcome_set.populate(log) - + def test_populate_longrepr(self): rev_outcome_set = summary.RevisionOutcomeSet('50000') log = StringIO("""F a/b.py:test_one @@ -90,7 +90,7 @@ s a/b.py:test_three some skip """) - + rev_outcome_set.populate(log) assert len(rev_outcome_set.skipped) == 1 @@ -115,7 +115,7 @@ F a/b.py:test_two \xc3\xa5 bar """) - + rev_outcome_set.populate(log) assert len(rev_outcome_set.failed) == 2 @@ -133,7 +133,7 @@ ! ! /a/b/c.py:92 """) - + rev_outcome_set.populate(log) assert rev_outcome_set.failed == set([ @@ -151,12 +151,12 @@ log = StringIO("""x a/b.py EXC """) - + rev_outcome_set.populate(log) assert rev_outcome_set.numxfailed == 1 - - + + def test_absent_outcome(self): rev_outcome_set = summary.RevisionOutcomeSet('50000') @@ -169,7 +169,7 @@ def load(x, y): calls.append(y) return y - + cache._load_outcome_set = load res = cache.get('status', 'a') @@ -183,14 +183,14 @@ cache.get('status', 'b') res = cache.get('status', 'c') assert res == 'c' - + assert calls == ['a', 'b', 'c'] calls = [] res = cache.get('status', 'd') assert res == 'd' assert cache.get('status', 'c') == 'c' - assert cache.get('status', 'b') == 'b' + assert cache.get('status', 'b') == 'b' assert calls == ['d'] res = cache.get('status', 'a') @@ -208,18 +208,18 @@ s a/b.py:test_three x a/b.py:test_four """) - + rev_outcome_set_foo.populate(log) - key_bar = ('bar', 7) + key_bar = ('bar', 7) rev_outcome_set_bar = summary.RevisionOutcomeSet('50000', key_bar) log = StringIO(""". a/b.py:test_one . a/b.py:test_two s a/b.py:test_three """) - + rev_outcome_set_bar.populate(log) d = {'foo': rev_outcome_set_foo, @@ -228,7 +228,7 @@ goutcome = summary.GatherOutcomeSet(d) assert goutcome.revision == '50000' - + assert goutcome.failed == set([('foo', 'a.b', 'test_one')]) assert goutcome.skipped == set([('foo', 'a.b', 'test_three'), @@ -273,14 +273,14 @@ assert res == ' ' res = goutcome_top.get_longrepr(('what', 'foo', 'a.b', 'test_one')) - assert res == '' + assert res == '' def test_colsizes(): failed = [('a', 'abc', 'd'), ('ab', 'c', 'xy'), ('ab', '', 'cd')] - + res = summary.colsizes(failed) - + assert res == [2,3,2] def test__prune_runs(): @@ -330,15 +330,15 @@ res = summary.show_elapsed(0.25) assert res == "0.25s" res = summary.show_elapsed(1.0) - assert res == "1.00s" + assert res == "1.00s" res = summary.show_elapsed(1.25) - assert res == "1.25s" + assert res == "1.25s" res = summary.show_elapsed(4.5) assert res == "4.50s" res = summary.show_elapsed(5.25) assert res == "5s" res = summary.show_elapsed(5.5) - assert res == "6s" + assert res == "6s" res = summary.show_elapsed(2*60+30) assert res == "2m30" res = summary.show_elapsed(4*60+30) @@ -348,22 +348,33 @@ res = summary.show_elapsed(61*60) assert res == "1h1" res = summary.show_elapsed(90*60) - assert res == "1h30" + assert res == "1h30" -def _BuilderToStatus(status): - setup = {'name': 'builder', 'builddir': 'BUILDDIR', - 'slavebuilddir': 'SLAVEBUILDDIR', - 'factory': process_factory.BuildFactory() } - return process_builder.Builder(setup, status) +class FakeMasterConfig(object): + buildbotURL = "http://buildbot/" + logCompressionLimit = 0 + def __init__(self, builders=None): + self.builders = builders + + +class FakeBuilderconfig(object): + validNames = 'name factory slavenames builddir slavebuilddir category ' \ + 'nextSlave nextBuild canStartBuild locks env properties ' \ + 'mergeRequests description'.split() + + def __init__(self, **kwargs): + for kw, item in kwargs.iteritems(): + assert kw in self.validNames + setattr(self, kw, item) class FakeMaster(object): basedir = None - buildbotURL = "http://buildbot/" def __init__(self, builders): self.botmaster = FakeBotMaster(builders) + self.config = FakeMasterConfig() def subscribeToBuildsetCompletions(self, callback): pass @@ -374,6 +385,7 @@ def subscribeToBuildRequests(self, callback): pass + class FakeBotMaster(object): def __init__(self, builders): @@ -384,19 +396,22 @@ self.builderNames.append(name) self.builders[name] = _BuilderToStatus(builder) + class FakeSite(object): def __init__(self, status): self.buildbot_service = FakeService(status) + class FakeService(object): - + def __init__(self, status): self.status = status def getStatus(self): return self.status + class FakeRequest(object): def __init__(self, builders, args={}): @@ -406,6 +421,14 @@ self.site = FakeSite(status) +def _BuilderToStatus(status): + builder = process_builder.Builder(status.name) + builder.builder_status = status + builder.builder_status.basedir = 'BASEDIR' + builder.config = FakeBuilderconfig(factory=process_factory.BuildFactory()) + return builder + + def witness_cat_branch(summary): ref = [None] recentRuns = summary.recentRuns @@ -414,7 +437,6 @@ ref[0] = cat_branch return cat_branch summary.recentRuns = witness - return lambda: ref[0] class FakeLog(object): @@ -424,7 +446,7 @@ self.step = step self.name = name self.cont = cont - + def getStep(self): return self.step @@ -444,7 +466,7 @@ n = getattr(builder, 'nextBuildNumber', 0) t = 1000 for rev, reslog in builds: - build = status_builder.BuildStatus(builder, n) + build = status_builder.BuildStatus(builder, builder.master, n) build.started = time.time() build.setProperty('got_revision', str(rev), None) step = build.addStepWithName('pytest') @@ -453,16 +475,21 @@ step.started = t step.finished = t + (n+1)*60 t = step.finished + 30 + builder.buildCache.cache[build.number] = build + builder.buildStarted(build) build.buildFinished() - builder.touchBuildCache(build) n += 1 builder.nextBuildNumber = n - + + +METABRANCH = '' + class TestSummary(object): def setup_method(self, meth): summary.outcome_set_cache.clear() + self.master = FakeMaster([]) def test_sanity(self): s = summary.Summary() @@ -474,79 +501,78 @@ assert cat_branch == {} def test_one_build_no_rev(self): - builder = status_builder.BuilderStatus('builder0') - build = status_builder.BuildStatus(builder, 0) - build.started = time.time() + builder = status_builder.BuilderStatus('builder0', None, self.master, '') + build = status_builder.BuildStatus(builder, self.master, 0) + build.buildStarted(builder) build.buildFinished() - builder.touchBuildCache(build) - builder.nextBuildNumber = len(builder.buildCache) + builder.nextBuildNumber = len(builder.buildCache.cache) s = summary.Summary() - res = witness_cat_branch(s) + res = witness_cat_branch(s) req = FakeRequest([builder]) out = s.body(req) cat_branch = res() - assert cat_branch == {(None, None): ({}, [build])} + assert cat_branch == {(None, METABRANCH): ({}, [build])} def test_one_build_no_logs(self): - builder = status_builder.BuilderStatus('builder0') - build = status_builder.BuildStatus(builder, 0) - build.started = time.time() + builder = status_builder.BuilderStatus('builder0', None, self.master, '') + build = status_builder.BuildStatus(builder, self.master, 0) + build.started = time.time() build.setProperty('got_revision', '50000', None) build.buildFinished() - builder.touchBuildCache(build) - builder.nextBuildNumber = len(builder.buildCache) + builder.buildCache.cache[build.number] = build + builder.nextBuildNumber = len(builder.buildCache.cache) s = summary.Summary() - res = witness_cat_branch(s) + res = witness_cat_branch(s) req = FakeRequest([builder]) out = s.body(req) cat_branch = res() - - revs = cat_branch[(None, None)][0] + + revs = cat_branch[(None, METABRANCH)][0] assert revs.keys() == ['50000'] - assert '<run>' in out + assert 'success' in out def test_one_build_no_logs_failure(self): - builder = status_builder.BuilderStatus('builder0') - build = status_builder.BuildStatus(builder, 0) - build.started = time.time() + builder = status_builder.BuilderStatus('builder0', None, self.master, '') + build = status_builder.BuildStatus(builder, self.master, 0) + build.started = time.time() build.setProperty('got_revision', '50000', None) step = build.addStepWithName('step') step.setText(['step', 'borken']) step.stepFinished(summary.FAILURE) step1 = build.addStepWithName('other') step1.setText(['other', 'borken']) - step1.stepFinished(summary.FAILURE) + step1.stepFinished(summary.FAILURE) build.buildFinished() - builder.touchBuildCache(build) - builder.nextBuildNumber = len(builder.buildCache) + builder.buildCache.cache[build.number] = build + builder.nextBuildNumber = len(builder.buildCache.cache) s = summary.Summary() - res = witness_cat_branch(s) - req = FakeRequest([builder]) - out = s.body(req) - cat_branch = res() - - revs = cat_branch[(None, None)][0] - assert revs.keys() == ['50000'] - - assert 'step borken' in out - assert 'other borken' not in out - - def test_one_build(self): - builder = status_builder.BuilderStatus('builder0') - add_builds(builder, [(60000, "F TEST1\n. b")]) - - s = summary.Summary() - res = witness_cat_branch(s) + res = witness_cat_branch(s) req = FakeRequest([builder]) out = s.body(req) cat_branch = res() - revs = cat_branch[(None, None)][0] + revs = cat_branch[(None, METABRANCH)][0] + assert revs.keys() == ['50000'] + + assert 'step borken' in out + assert 'other borken' not in out + + def test_one_build(self): + builder = status_builder.BuilderStatus('builder0', None, self.master, '') + add_builds(builder, [(60000, "F TEST1\n. b")]) + + s = summary.Summary() + res = witness_cat_branch(s) + req = FakeRequest([builder]) + out = s.body(req) + cat_branch = res() + + revs = cat_branch[(None, METABRANCH)][0] assert revs.keys() == ['60000'] outcome = revs['60000']['builder0'] assert outcome.revision == '60000' @@ -555,17 +581,17 @@ assert 'TEST1' in out def test_two_builds(self): - builder = status_builder.BuilderStatus('builder0') + builder = status_builder.BuilderStatus('builder0', None, self.master, '') add_builds(builder, [('60000', "F TEST1\n. b"), ('60001', ". TEST1\n. b")]) s = summary.Summary() - res = witness_cat_branch(s) + res = witness_cat_branch(s) req = FakeRequest([builder]) out = s.body(req) cat_branch = res() - revs = cat_branch[(None, None)][0] + revs = cat_branch[(None, METABRANCH)][0] assert sorted(revs.keys()) == ['60000', '60001'] outcome = revs['60000']['builder0'] assert outcome.revision == '60000' @@ -582,20 +608,21 @@ assert 'TEST1' in out assert ':-)' in out - assert '\n - + success' in out - + assert re.search(r'\n - ' + r'\+ success', out) is not None def test_two_builds_samerev(self): - builder = status_builder.BuilderStatus('builder0') + builder = status_builder.BuilderStatus('builder0', None, self.master, '') add_builds(builder, [('60000', "F TEST1\n. b"), - ('60000', "F TEST1\n. b")]) + ('60000', "F TEST1\n. b")]) s = summary.Summary() - res = witness_cat_branch(s) + res = witness_cat_branch(s) req = FakeRequest([builder]) out = s.body(req) cat_branch = res() - revs = cat_branch[(None, None)][0] + revs = cat_branch[(None, METABRANCH)][0] assert sorted(revs.keys()) == ['60000'] outcome = revs['60000']['builder0'] assert outcome.revision == '60000' @@ -604,18 +631,18 @@ assert 'TEST1' in out def test_two_builds_recentrev(self): - builder = status_builder.BuilderStatus('builder0') + builder = status_builder.BuilderStatus('builder0', None, self.master, '') add_builds(builder, [('60000', "F TEST1\n. b"), ('60001', "F TEST1\n. b")]) s = summary.Summary() - res = witness_cat_branch(s) + res = witness_cat_branch(s) req = FakeRequest([builder]) req.args = {'recentrev': ['60000']} out = s.body(req) cat_branch = res() - revs = cat_branch[(None, None)][0] + revs = cat_branch[(None, METABRANCH)][0] assert sorted(revs.keys()) == ['60000'] outcome = revs['60000']['builder0'] assert outcome.revision == '60000' @@ -624,19 +651,19 @@ assert 'TEST1' in out def test_many_builds_query_builder(self): - builder = status_builder.BuilderStatus('builder0') + builder = status_builder.BuilderStatus('builder0', None, self.master, '') add_builds(builder, [('60000', "F TEST1\n. b"), ('60000', ". a\n. b"), - ('60001', "F TEST1\n. b")]) + ('60001', "F TEST1\n. b")]) s = summary.Summary() - res = witness_cat_branch(s) + res = witness_cat_branch(s) req = FakeRequest([builder]) req.args={'builder': ['builder0']} out = s.body(req) cat_branch = res() - runs = cat_branch[(None, None)][0] + runs = cat_branch[(None, METABRANCH)][0] assert sorted(runs.keys()) == [(0, '60000'), (1, '60000'), (2, '60001')] outcome = runs[(0, '60000')]['builder0'] assert outcome.revision == '60000' @@ -660,20 +687,20 @@ def test_many_builds_query_builder_builds(self): - builder = status_builder.BuilderStatus('builder0') + builder = status_builder.BuilderStatus('builder0', None, self.master, '') add_builds(builder, [('60000', "F TEST1\n. b"), ('60000', ". a\n. b"), - ('60001', "F TEST1\n. b")]) + ('60001', "F TEST1\n. b")]) s = summary.Summary() - res = witness_cat_branch(s) + res = witness_cat_branch(s) req = FakeRequest([builder]) req.args={'builder': ['builder0'], 'builds': ['0','2-2', '7']} out = s.body(req) cat_branch = res() - runs = cat_branch[(None, None)][0] + runs = cat_branch[(None, METABRANCH)][0] assert sorted(runs.keys()) == [(0, '60000'), (2, '60001')] outcome = runs[(0, '60000')]['builder0'] assert outcome.revision == '60000' @@ -692,21 +719,21 @@ assert 'TEST1' in out def test_many_pytestLogs(self): - builder = status_builder.BuilderStatus('builder1') - build = status_builder.BuildStatus(builder, 0) + builder = status_builder.BuilderStatus('builder1', '', self.master, '') + build = status_builder.BuildStatus(builder, self.master, 0) build.started = time.time() build.setProperty('got_revision', '70000', None) step = build.addStepWithName('pytest') step.logs.extend([FakeLog(step, 'pytestLog', "F TEST1")]) step.setText(["pytest", "failed"]) - step.stepFinished(summary.FAILURE) + step.stepFinished(summary.FAILURE) step2 = build.addStepWithName('pytest2') step2.logs.extend([FakeLog(step, 'pytestLog', ". x\nF TEST2")]) step2.setText(["pytest2", "aborted"]) step2.stepFinished(summary.EXCEPTION) build.buildFinished() - builder.touchBuildCache(build) - builder.nextBuildNumber = 1 + builder.buildCache.cache[build.number] = build + builder.nextBuildNumber = len(builder.buildCache.cache) s = summary.Summary() req = FakeRequest([builder]) @@ -719,23 +746,23 @@ assert 'pytest2 aborted' in out def test_subtle_failures(self): - builder = status_builder.BuilderStatus('builder1') - build = status_builder.BuildStatus(builder, 0) + builder = status_builder.BuilderStatus('builder1', '', self.master, '') + build = status_builder.BuildStatus(builder, self.master, 0) build.started = time.time() build.setProperty('got_revision', '70000', None) - step = build.addStepWithName('pytest') + step = build.addStepWithName('pytest') step.logs.extend([FakeLog(step, 'pytestLog', ". TEST1")]) step.setText(["pytest", "failed slave lost"]) - step.stepFinished(summary.FAILURE) + step.stepFinished(summary.FAILURE) build.buildFinished() - builder.touchBuildCache(build) - builder.nextBuildNumber = 1 + builder.buildCache.cache[build.number] = build + builder.nextBuildNumber = len(builder.buildCache.cache) s = summary.Summary() req = FakeRequest([builder]) out = s.body(req) - assert 'pytest failed slave lost' in out + assert 'pytest failed slave lost' in out def test_category_branch_sorting_key(self): @@ -764,19 +791,16 @@ assert res == (2, '', 2, 'release/1') res = s._cat_branch_key(('', 'what')) - assert res == (2, '', 4, 'what') + assert res == (2, '', 4, 'what') def test_builders_with_categories(self): - builder1 = status_builder.BuilderStatus('builder_foo') - builder1.category = 'foo' - builder2 = status_builder.BuilderStatus('builder_bar') - builder2.category = 'bar' - builder3 = status_builder.BuilderStatus('builder_') - builder3.category = '' + builder1 = status_builder.BuilderStatus('builder_foo', 'foo', self.master, '') + builder2 = status_builder.BuilderStatus('builder_bar', 'bar', self.master, '') + builder3 = status_builder.BuilderStatus('builder_', '', self.master, '') add_builds(builder1, [('60000', "F TEST1\n")]) add_builds(builder2, [('60000', "F TEST2\n")]) - add_builds(builder3, [('60000', "F TEST3\n")]) + add_builds(builder3, [('60000', "F TEST3\n")]) s = summary.Summary(['foo', 'bar']) req = FakeRequest([builder1, builder2, builder3]) @@ -792,7 +816,7 @@ assert "{bar}" in out def test_two_builds_different_rev_digits(self): - builder = status_builder.BuilderStatus('builder0') + builder = status_builder.BuilderStatus('builder0', '', self.master, '') add_builds(builder, [(999, "F TEST1\n. b"), (1000, "F TEST1\n. b")]) @@ -806,16 +830,16 @@ assert p999builder0-p999 == p1000builder0-p1000+1 def test_build_times_and_filtering(self): - builder1 = status_builder.BuilderStatus('builder1') - builder2 = status_builder.BuilderStatus('builder2') - + builder1 = status_builder.BuilderStatus('builder1', '', self.master, '') + builder2 = status_builder.BuilderStatus('builder2', '', self.master, '') + add_builds(builder1, [('60000', "F TEST1\n")]) - add_builds(builder2, [('50000', ". TEST2\n")]) + add_builds(builder2, [('50000', ". TEST2\n")]) add_builds(builder2, [('60000', "F TEST2\n")]) builder1.getBuild(0).started = 1228258800 # 3 Dec 2008 builder1.getBuild(0).finished = 1228258800 # 3 Dec 2008 - builder2.getBuild(1).started = 1228431600 # 5 Dec 2008 + builder2.getBuild(1).started = 1228431600 # 5 Dec 2008 builder2.getBuild(1).finished = 1228431600 # 5 Dec 2008 builder2.getBuild(0).started = 1227913200 # 29 Nov 2008 diff --git a/bot2/pypybuildbot/util.py b/bot2/pypybuildbot/util.py --- a/bot2/pypybuildbot/util.py +++ b/bot2/pypybuildbot/util.py @@ -2,7 +2,7 @@ import socket def we_are_debugging(): - return socket.gethostname() not in ("wyvern", "cobra") + return socket.gethostname() != 'cobra' def load(name): mod = __import__(name, {}, {}, ['__all__']) diff --git a/master/public_html/default.css b/master/public_html/default.css --- a/master/public_html/default.css +++ b/master/public_html/default.css @@ -10,6 +10,22 @@ color: #333; } +.auth { +position:absolute; +top:5px; +right:40px; +} + +.alert { + color: #c30000; + background-color: #f2dcdc; + padding: 5px 5px 5px 25px; + margin-bottom: 20px; + border-top:1px solid #ccc; + border-bottom:1px solid #ccc; + border-color: #c30000; + font-size: 20px; +} a:link,a:visited,a:active { color: #444; } @@ -197,14 +213,17 @@ font-weight: normal; padding: 8px 8px 8px 8px; color: #333333; + background-color: #eee; + text-align: left; +} + +td.DevBottom { border-bottom-right-radius: 5px; -webkit-border-bottom-right-radius: 5px; -moz-border-radius-bottomright: 5px; border-bottom-left-radius: 5px; -webkit-border-bottom-left-radius: 5px; -moz-border-radius-bottomleft: 5px; - background-color: #eee; - text-align: left; } td.Alt { @@ -212,9 +231,9 @@ } .legend { - border-radius: 5px; - -webkit-border-radius: 5px; - -moz-border-radius: 5px; + border-radius: 5px !important; + -webkit-border-radius: 5px !important; + -moz-border-radius: 5px !important; width: 100px; max-width: 100px; text-align: center; @@ -349,6 +368,12 @@ border-color: #A77272; } +.failure-again { + color: #000; + background-color: #eA9; + border-color: #A77272; +} + .warnings { color: #FFFFFF; background-color: #fa3; @@ -379,6 +404,12 @@ border-color: #C5C56D; } +.paused { + color: #FFFFFF; + background-color: #8080FF; + border-color: #dddddd; +} + .offline,td.offline { color: #FFFFFF; background-color: #777777; @@ -534,6 +565,10 @@ display: none; } +pre { + white-space: pre-wrap; +} + /* change comments (use regular colors here) */ pre.comments>a:link,pre.comments>a:visited { color: blue; @@ -542,3 +577,27 @@ pre.comments>a:active { color: purple; } + +form.command_forcebuild { + border-top: 1px solid black; + padding: .5em; + margin: .5em; +} + +form.command_forcebuild > .row { + border-top: 1px dotted gray; + padding: .5em 0; +} + +form.command_forcebuild .force-textarea > .label { + display: block; +} + +form.command_forcebuild .force-nested > .label { + font-weight: bold; + display: list-item; +} + +form.command_forcebuild .force-any .force-text { + display: inline; +} diff --git a/master/public_html/favicon.ico b/master/public_html/favicon.ico new file mode 100644 index 0000000000000000000000000000000000000000..b0b0845dce40e4845f7e7251b37b78a40b34c961 GIT binary patch [cut] diff --git a/master/public_html/index.html b/master/public_html/index.html --- a/master/public_html/index.html +++ b/master/public_html/index.html @@ -10,10 +10,10 @@ {% else %}

No current builds

-{% endif %} - +{% endif %} + {% if pending %}

Pending Build Requests:

    {% for b in pending %} -
  • ({{ b.when }}, waiting {{ b.delay }}) - - {% if authz.advertiseAction('cancelPendingBuild') %} +
  • ({{ b.when }}, waiting {{ b.delay }}) + + {% if authz.advertiseAction('cancelPendingBuild', request) %} {{ forms.cancel_pending_build(builder_url+"/cancelbuild", authz, short=True, id=b.id) }} - {% endif %} - + {% endif %} + {% if b.num_changes < 4 %} {% for c in b.changes %}{{ c.revision|shortrev(c.repo) }} - ({{ c.who }}){% if not loop.last %},{% endif %} + ({{ c.who|email }}){% if not loop.last %},{% endif %} {% endfor %} {% else %} ({{ b.num_changes }} changes) - {% endif %} + {% endif %} + {% if 'owner' in b.properties %} + Forced build + by {{b.properties['owner'][0]}} + {{b.properties['reason'][0]}} + {% endif %}
  • From noreply at buildbot.pypy.org Tue Sep 3 14:55:15 2013 From: noreply at buildbot.pypy.org (bivab) Date: Tue, 3 Sep 2013 14:55:15 +0200 (CEST) Subject: [pypy-commit] buildbot buildbot-update: close branch Message-ID: <20130903125515.EF0F61D1F53@cobra.cs.uni-duesseldorf.de> Author: David Schneider Branch: buildbot-update Changeset: r851:b3c52215978f Date: 2013-09-03 14:54 +0200 http://bitbucket.org/pypy/buildbot/changeset/b3c52215978f/ Log: close branch From noreply at buildbot.pypy.org Tue Sep 3 19:34:11 2013 From: noreply at buildbot.pypy.org (bivab) Date: Tue, 3 Sep 2013 19:34:11 +0200 (CEST) Subject: [pypy-commit] buildbot default: add an own-test builder on greenbox0, not scheduled yet Message-ID: <20130903173411.24F941D23A6@cobra.cs.uni-duesseldorf.de> Author: David Schneider Branch: Changeset: r852:b8180d9b633e Date: 2013-07-29 13:54 +0200 http://bitbucket.org/pypy/buildbot/changeset/b8180d9b633e/ Log: add an own-test builder on greenbox0, not scheduled yet diff --git a/bot2/pypybuildbot/arm_master.py b/bot2/pypybuildbot/arm_master.py --- a/bot2/pypybuildbot/arm_master.py +++ b/bot2/pypybuildbot/arm_master.py @@ -100,6 +100,7 @@ platform='linux-armhf-raring', ) # +LINUXARMHF = "own-linux-armhf" APPLVLLINUXARM = "pypy-c-app-level-linux-armel" APPLVLLINUXARMHF_v7 = "pypy-c-app-level-linux-armhf-v7" APPLVLLINUXARMHF_RASPBIAN = "pypy-c-app-level-linux-armhf-raspbian" @@ -178,6 +179,12 @@ "locks": [ARMBoardLock.access('counting')], }, ## armv7 + {"name": LINUXARMHF, + "slavenames": ["greenbox3-node0"], + "builddir": LINUXARMHF, + "factory": pypyOwnTestFactoryARM, + "category": 'linux-armhf', + }, {"name": JITBACKENDONLYLINUXARMHF_v7, "slavenames": ['cubieboard-bob'], "builddir": JITBACKENDONLYLINUXARMHF_v7, From noreply at buildbot.pypy.org Tue Sep 3 19:34:12 2013 From: noreply at buildbot.pypy.org (bivab) Date: Tue, 3 Sep 2013 19:34:12 +0200 (CEST) Subject: [pypy-commit] buildbot default: reset permissions of file being copied around Message-ID: <20130903173412.9F0FF1D23A7@cobra.cs.uni-duesseldorf.de> Author: David Schneider Branch: Changeset: r853:60936febc1bc Date: 2013-09-03 19:31 +0200 http://bitbucket.org/pypy/buildbot/changeset/60936febc1bc/ Log: reset permissions of file being copied around diff --git a/bot2/pypybuildbot/builds.py b/bot2/pypybuildbot/builds.py --- a/bot2/pypybuildbot/builds.py +++ b/bot2/pypybuildbot/builds.py @@ -394,6 +394,11 @@ haltOnFailure=True, )) + self.addStep(ShellCmd( + description="reset permissions", + command=['chmod', 'u+rw', '-R', 'build/include'], + haltOnFailure=True, + workdir='.')) # copy pypy-c to the expected location within the pypy source checkout self.addStep(ShellCmd( description="move pypy-c", @@ -408,6 +413,11 @@ workdir='.')) # copy ctypes_resource_cache generated during translation self.addStep(ShellCmd( + description="reset permissions", + command=['chmod', 'u+rw', '-R', 'build/lib_pypy'], + haltOnFailure=True, + workdir='.')) + self.addStep(ShellCmd( description="move ctypes resource cache", command=['cp', '-rv', 'pypy-c/lib_pypy/ctypes_config_cache', 'build/lib_pypy'], haltOnFailure=True, From noreply at buildbot.pypy.org Tue Sep 3 19:34:13 2013 From: noreply at buildbot.pypy.org (bivab) Date: Tue, 3 Sep 2013 19:34:13 +0200 (CEST) Subject: [pypy-commit] buildbot default: merge heads Message-ID: <20130903173413.CE9071D23A9@cobra.cs.uni-duesseldorf.de> Author: David Schneider Branch: Changeset: r854:299b69d2e736 Date: 2013-09-03 19:33 +0200 http://bitbucket.org/pypy/buildbot/changeset/299b69d2e736/ Log: merge heads diff --git a/bot2/pypybuildbot/arm_master.py b/bot2/pypybuildbot/arm_master.py --- a/bot2/pypybuildbot/arm_master.py +++ b/bot2/pypybuildbot/arm_master.py @@ -100,6 +100,7 @@ platform='linux-armhf-raring', ) # +LINUXARMHF = "own-linux-armhf" APPLVLLINUXARM = "pypy-c-app-level-linux-armel" APPLVLLINUXARMHF_v7 = "pypy-c-app-level-linux-armhf-v7" APPLVLLINUXARMHF_RASPBIAN = "pypy-c-app-level-linux-armhf-raspbian" @@ -193,6 +194,12 @@ "locks": [ARMBoardLock.access('counting')], }, ## armv7 + {"name": LINUXARMHF, + "slavenames": ["greenbox3-node0"], + "builddir": LINUXARMHF, + "factory": pypyOwnTestFactoryARM, + "category": 'linux-armhf', + }, {"name": JITBACKENDONLYLINUXARMHF_v7, "slavenames": ['cubieboard-bob'], "builddir": JITBACKENDONLYLINUXARMHF_v7, From noreply at buildbot.pypy.org Tue Sep 3 19:39:05 2013 From: noreply at buildbot.pypy.org (bivab) Date: Tue, 3 Sep 2013 19:39:05 +0200 (CEST) Subject: [pypy-commit] buildbot default: add ARM own-test builder to the force scheduler Message-ID: <20130903173906.00DFD1C0EFC@cobra.cs.uni-duesseldorf.de> Author: David Schneider Branch: Changeset: r855:82b98d0800c9 Date: 2013-09-03 19:38 +0200 http://bitbucket.org/pypy/buildbot/changeset/82b98d0800c9/ Log: add ARM own-test builder to the force scheduler diff --git a/bbhook/main.py b/bbhook/main.py --- a/bbhook/main.py +++ b/bbhook/main.py @@ -38,8 +38,9 @@ @app.route('/', methods=['POST']) def handle_payload(): - payload = json.loads(flask.request.form['payload']) + open('/tmp/payload', 'w').write(flask.request.form['payload']) try: + payload = json.loads(flask.request.form['payload']) from . import hook hook.handle(payload, test=app.testing) except: diff --git a/bot2/pypybuildbot/arm_master.py b/bot2/pypybuildbot/arm_master.py --- a/bot2/pypybuildbot/arm_master.py +++ b/bot2/pypybuildbot/arm_master.py @@ -122,6 +122,7 @@ BUILDJITLINUXARMHF_RARING = "build-pypy-c-jit-linux-armhf-raring" builderNames = [ + LINUXARMHF, APPLVLLINUXARM, APPLVLLINUXARMHF_v7, APPLVLLINUXARMHF_RASPBIAN, From noreply at buildbot.pypy.org Tue Sep 3 20:45:11 2013 From: noreply at buildbot.pypy.org (wlav) Date: Tue, 3 Sep 2013 20:45:11 +0200 (CEST) Subject: [pypy-commit] pypy reflex-support: merge default into branch Message-ID: <20130903184511.5A37F1C135D@cobra.cs.uni-duesseldorf.de> Author: Wim Lavrijsen Branch: reflex-support Changeset: r66779:aebf8cc7108a Date: 2013-09-03 11:43 -0700 http://bitbucket.org/pypy/pypy/changeset/aebf8cc7108a/ Log: merge default into branch diff too long, truncating to 2000 out of 10055 lines diff --git a/lib-python/2.7/uuid.py b/lib-python/2.7/uuid.py --- a/lib-python/2.7/uuid.py +++ b/lib-python/2.7/uuid.py @@ -44,6 +44,8 @@ UUID('00010203-0405-0607-0809-0a0b0c0d0e0f') """ +import struct + __author__ = 'Ka-Ping Yee ' RESERVED_NCS, RFC_4122, RESERVED_MICROSOFT, RESERVED_FUTURE = [ @@ -125,25 +127,38 @@ overriding the given 'hex', 'bytes', 'bytes_le', 'fields', or 'int'. """ - if [hex, bytes, bytes_le, fields, int].count(None) != 4: - raise TypeError('need one of hex, bytes, bytes_le, fields, or int') if hex is not None: + if (bytes is not None or bytes_le is not None or fields is not None + or int is not None): + raise TypeError('if the hex argument is given, bytes, bytes_le, fields,' + ' and int need to be None') hex = hex.replace('urn:', '').replace('uuid:', '') hex = hex.strip('{}').replace('-', '') if len(hex) != 32: raise ValueError('badly formed hexadecimal UUID string') int = long(hex, 16) - if bytes_le is not None: + elif bytes_le is not None: + if bytes is not None or fields is not None or int is not None: + raise TypeError('if the bytes_le argument is given, bytes, fields,' + ' and int need to be None') if len(bytes_le) != 16: raise ValueError('bytes_le is not a 16-char string') bytes = (bytes_le[3] + bytes_le[2] + bytes_le[1] + bytes_le[0] + bytes_le[5] + bytes_le[4] + bytes_le[7] + bytes_le[6] + bytes_le[8:]) - if bytes is not None: + int = (struct.unpack('>Q', bytes[:8])[0] << 64 | + struct.unpack('>Q', bytes[8:])[0]) + elif bytes is not None: + if fields is not None or int is not None: + raise TypeError('if the bytes argument is given, fields' + ' and int need to be None') if len(bytes) != 16: raise ValueError('bytes is not a 16-char string') - int = long(('%02x'*16) % tuple(map(ord, bytes)), 16) - if fields is not None: + int = (struct.unpack('>Q', bytes[:8])[0] << 64 | + struct.unpack('>Q', bytes[8:])[0]) + elif fields is not None: + if int is not None: + raise TypeError('if the fields argument is given, int needs to be None') if len(fields) != 6: raise ValueError('fields is not a 6-tuple') (time_low, time_mid, time_hi_version, @@ -163,9 +178,12 @@ clock_seq = (clock_seq_hi_variant << 8L) | clock_seq_low int = ((time_low << 96L) | (time_mid << 80L) | (time_hi_version << 64L) | (clock_seq << 48L) | node) - if int is not None: + elif int is not None: if not 0 <= int < 1<<128L: raise ValueError('int is out of range (need a 128-bit value)') + else: + raise TypeError('one of hex, bytes, bytes_le, fields,' + ' or int need to be not None') if version is not None: if not 1 <= version <= 5: raise ValueError('illegal version number') @@ -175,7 +193,7 @@ # Set the version number. int &= ~(0xf000 << 64L) int |= version << 76L - self.__dict__['int'] = int + object.__setattr__(self, 'int', int) def __cmp__(self, other): if isinstance(other, UUID): diff --git a/lib_pypy/_curses.py b/lib_pypy/_curses.py --- a/lib_pypy/_curses.py +++ b/lib_pypy/_curses.py @@ -1,6 +1,9 @@ """Reimplementation of the standard extension module '_curses' using cffi.""" import sys +if sys.platform == 'win32': + #This module does not exist in windows + raise ImportError('No module named _curses') from functools import wraps from cffi import FFI diff --git a/lib_pypy/_sqlite3.py b/lib_pypy/_sqlite3.py --- a/lib_pypy/_sqlite3.py +++ b/lib_pypy/_sqlite3.py @@ -1229,7 +1229,10 @@ if cvt is not None: param = cvt(param) - param = adapt(param) + try: + param = adapt(param) + except: + pass # And use previous value if param is None: rc = _lib.sqlite3_bind_null(self._statement, idx) diff --git a/lib_pypy/cffi/__init__.py b/lib_pypy/cffi/__init__.py --- a/lib_pypy/cffi/__init__.py +++ b/lib_pypy/cffi/__init__.py @@ -4,5 +4,5 @@ from .api import FFI, CDefError, FFIError from .ffiplatform import VerificationError, VerificationMissing -__version__ = "0.7" -__version_info__ = (0, 7) +__version__ = "0.7.2" +__version_info__ = (0, 7, 2) diff --git a/lib_pypy/cffi/api.py b/lib_pypy/cffi/api.py --- a/lib_pypy/cffi/api.py +++ b/lib_pypy/cffi/api.py @@ -54,7 +54,8 @@ # _cffi_backend.so compiled. import _cffi_backend as backend from . import __version__ - assert backend.__version__ == __version__ + assert (backend.__version__ == __version__ or + backend.__version__ == __version__[:3]) # (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.) diff --git a/lib_pypy/cffi/commontypes.py b/lib_pypy/cffi/commontypes.py --- a/lib_pypy/cffi/commontypes.py +++ b/lib_pypy/cffi/commontypes.py @@ -30,7 +30,9 @@ elif result in model.PrimitiveType.ALL_PRIMITIVE_TYPES: result = model.PrimitiveType(result) else: - assert commontype != result + if commontype == result: + raise api.FFIError("Unsupported type: %r. Please file a bug " + "if you think it should be." % (commontype,)) result = resolve_common_type(result) # recursively assert isinstance(result, model.BaseTypeByIdentity) _CACHE[commontype] = result diff --git a/lib_pypy/cffi/cparser.py b/lib_pypy/cffi/cparser.py --- a/lib_pypy/cffi/cparser.py +++ b/lib_pypy/cffi/cparser.py @@ -290,13 +290,26 @@ # assume a primitive type. get it from .names, but reduce # synonyms to a single chosen combination names = list(type.names) - if names == ['signed'] or names == ['unsigned']: - names.append('int') - if names[0] == 'signed' and names != ['signed', 'char']: - names.pop(0) - if (len(names) > 1 and names[-1] == 'int' - and names != ['unsigned', 'int']): - names.pop() + if names != ['signed', 'char']: # keep this unmodified + prefixes = {} + while names: + name = names[0] + if name in ('short', 'long', 'signed', 'unsigned'): + prefixes[name] = prefixes.get(name, 0) + 1 + del names[0] + else: + break + # ignore the 'signed' prefix below, and reorder the others + newnames = [] + for prefix in ('unsigned', 'short', 'long'): + for i in range(prefixes.get(prefix, 0)): + newnames.append(prefix) + if not names: + names = ['int'] # implicitly + if names == ['int']: # but kill it if 'short' or 'long' + if 'short' in prefixes or 'long' in prefixes: + names = [] + names = newnames + names ident = ' '.join(names) if ident == 'void': return model.void_type @@ -500,8 +513,8 @@ self._partial_length = True return None # - raise api.FFIError("unsupported non-constant or " - "not immediately constant expression") + raise api.FFIError("unsupported expression: expected a " + "simple numeric constant") def _build_enum_type(self, explicit_name, decls): if decls is not None: diff --git a/lib_pypy/cffi/vengine_gen.py b/lib_pypy/cffi/vengine_gen.py --- a/lib_pypy/cffi/vengine_gen.py +++ b/lib_pypy/cffi/vengine_gen.py @@ -61,7 +61,9 @@ def load_library(self): # import it with the CFFI backend backend = self.ffi._backend - module = backend.load_library(self.verifier.modulefilename) + # needs to make a path that contains '/', on Posix + filename = os.path.join(os.curdir, self.verifier.modulefilename) + module = backend.load_library(filename) # # call loading_gen_struct() to get the struct layout inferred by # the C compiler diff --git a/lib_pypy/datetime.py b/lib_pypy/datetime.py --- a/lib_pypy/datetime.py +++ b/lib_pypy/datetime.py @@ -40,9 +40,9 @@ # for all computations. See the book for algorithms for converting between # proleptic Gregorian ordinals and many other calendar systems. -_DAYS_IN_MONTH = [None, 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31] +_DAYS_IN_MONTH = [-1, 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31] -_DAYS_BEFORE_MONTH = [None] +_DAYS_BEFORE_MONTH = [-1] dbm = 0 for dim in _DAYS_IN_MONTH[1:]: _DAYS_BEFORE_MONTH.append(dbm) diff --git a/pypy/config/pypyoption.py b/pypy/config/pypyoption.py --- a/pypy/config/pypyoption.py +++ b/pypy/config/pypyoption.py @@ -127,11 +127,6 @@ pypy_optiondescription = OptionDescription("objspace", "Object Space Options", [ - OptionDescription("opcodes", "opcodes to enable in the interpreter", [ - BoolOption("CALL_METHOD", "emit a special bytecode for expr.name()", - default=False), - ]), - OptionDescription("usemodules", "Which Modules should be used", [ BoolOption(modname, "use module %s" % (modname, ), default=modname in default_modules, @@ -259,9 +254,6 @@ BoolOption("optimized_int_add", "special case the addition of two integers in BINARY_ADD", default=False), - BoolOption("optimized_comparison_op", - "special case the comparison of integers", - default=False), BoolOption("optimized_list_getitem", "special case the 'list[integer]' expressions", default=False), @@ -307,7 +299,6 @@ # all the good optimizations for PyPy should be listed here if level in ['2', '3', 'jit']: - config.objspace.opcodes.suggest(CALL_METHOD=True) config.objspace.std.suggest(withrangelist=True) config.objspace.std.suggest(withmethodcache=True) config.objspace.std.suggest(withprebuiltchar=True) diff --git a/pypy/doc/coding-guide.rst b/pypy/doc/coding-guide.rst --- a/pypy/doc/coding-guide.rst +++ b/pypy/doc/coding-guide.rst @@ -339,9 +339,10 @@ + methods and other class attributes do not change after startup + single inheritance is fully supported -+ simple mixins somewhat work too, but the mixed in class needs a - ``_mixin_ = True`` class attribute. isinstance checks against the - mixin type will fail when translated. ++ use `rpython.rlib.objectmodel.import_from_mixin(M)` in a class + body to copy the whole content of a class `M`. This can be used + to implement mixins: functions and staticmethods are duplicated + (the other class attributes are just copied unmodified). + classes are first-class objects too diff --git a/pypy/doc/config/objspace.opcodes.CALL_METHOD.txt b/pypy/doc/config/objspace.opcodes.CALL_METHOD.txt deleted file mode 100644 --- a/pypy/doc/config/objspace.opcodes.CALL_METHOD.txt +++ /dev/null @@ -1,10 +0,0 @@ -Enable a pair of bytecodes that speed up method calls. -See ``pypy.interpreter.callmethod`` for a description. - -The goal is to avoid creating the bound method object in the common -case. So far, this only works for calls with no keyword, no ``*arg`` -and no ``**arg`` but it would be easy to extend. - -For more information, see the section in `Standard Interpreter Optimizations`_. - -.. _`Standard Interpreter Optimizations`: ../interpreter-optimizations.html#lookup-method-call-method diff --git a/pypy/doc/config/objspace.opcodes.txt b/pypy/doc/config/objspace.opcodes.txt deleted file mode 100644 --- a/pypy/doc/config/objspace.opcodes.txt +++ /dev/null @@ -1,1 +0,0 @@ -.. intentionally empty 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 @@ -57,6 +57,12 @@ zlib-devel bzip2-devel ncurses-devel expat-devel \ openssl-devel gc-devel python-sphinx python-greenlet + On SLES11: + + $ sudo zypper install gcc make python-devel pkg-config \ + zlib-devel libopenssl-devel libbz2-devel sqlite3-devel \ + libexpat-devel libffi-devel python-curses + The above command lines are split with continuation characters, giving the necessary dependencies first, then the optional ones. * ``pkg-config`` (to help us locate libffi files) 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 @@ -198,9 +198,6 @@ if it is not None, then it is considered to be an additional first argument in the call to the *im_func* object from the stack. -You can enable this feature with the :config:`objspace.opcodes.CALL_METHOD` -option. - .. more here? Overall Effects diff --git a/pypy/doc/tool/makecontributor.py b/pypy/doc/tool/makecontributor.py --- a/pypy/doc/tool/makecontributor.py +++ b/pypy/doc/tool/makecontributor.py @@ -60,6 +60,11 @@ 'Roberto De Ioris': ['roberto at mrspurr'], 'Sven Hager': ['hager'], 'Tomo Cocoa': ['cocoatomo'], + 'Romain Guillebert': ['rguillebert', 'rguillbert', 'romain', 'Guillebert Romain'], + 'Ronan Lamy': ['ronan'], + 'Edd Barrett': ['edd'], + 'Manuel Jacob': ['mjacob'], + 'Rami Chowdhury': ['necaris'], } alias_map = {} @@ -80,7 +85,8 @@ if not match: return set() ignore_words = ['around', 'consulting', 'yesterday', 'for a bit', 'thanks', - 'in-progress', 'bits of', 'even a little', 'floating',] + 'in-progress', 'bits of', 'even a little', 'floating', + 'a bit', 'reviewing'] sep_words = ['and', ';', '+', '/', 'with special by'] nicknames = match.group(1) for word in ignore_words: @@ -119,7 +125,7 @@ ## print '%5d %s' % (n, name) ## else: ## print name - + items = authors_count.items() items.sort(key=operator.itemgetter(1), reverse=True) for name, n in items: 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 @@ -5,6 +5,11 @@ .. this is a revision shortly after release-2.1-beta .. startrev: 4eb52818e7c0 +.. branch: sanitise_bytecode_dispatch +Make PyPy's bytecode dispatcher easy to read, and less reliant on RPython +magic. There is no functional change, though the removal of dead code leads +to many fewer tests to execute. + .. branch: fastjson Fast json decoder written in RPython, about 3-4x faster than the pure Python decoder which comes with the stdlib @@ -74,3 +79,18 @@ .. branch: dotviewer-linewidth .. branch: reflex-support .. branch: numpypy-inplace-op +.. branch: rewritten-loop-logging + +.. branch: nobold-backtrace +Work on improving UnionError messages and stack trace displays. + +.. branch: improve-errors-again +More improvements and refactorings of error messages. + +.. branch: improve-errors-again2 +Unbreak tests in rlib. + +.. branch: less-stringly-ops +Use subclasses of SpaceOperation instead of SpaceOperator objects. +Random cleanups in flowspace. + diff --git a/pypy/doc/windows.rst b/pypy/doc/windows.rst --- a/pypy/doc/windows.rst +++ b/pypy/doc/windows.rst @@ -6,6 +6,10 @@ The following text gives some hints about how to translate the PyPy interpreter. +PyPy supports only being translated as a 32bit program, even on +64bit Windows. See at the end of this page for what is missing +for a full 64bit translation. + To build pypy-c you need a C compiler. Microsoft Visual Studio is preferred, but can also use the mingw32 port of gcc. @@ -63,7 +67,7 @@ INCLUDE, LIB and PATH (for DLLs) environment variables appropriately. Abridged method (for -Ojit builds using Visual Studio 2008) -~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ Download the versions of all the external packages from https://bitbucket.org/pypy/pypy/downloads/local.zip @@ -112,13 +116,14 @@ nmake -f makefile.msc The sqlite3 database library -~~~~~~~~~~~~~~~~~~~~ +~~~~~~~~~~~~~~~~~~~~~~~~~~~~ Download http://www.sqlite.org/2013/sqlite-amalgamation-3071601.zip and extract it into a directory under the base directory. Also get http://www.sqlite.org/2013/sqlite-dll-win32-x86-3071601.zip and extract the dll into the bin directory, and the sqlite3.def into the sources directory. Now build the import library so cffi can use the header and dll:: + lib /DEF:sqlite3.def" /OUT:sqlite3.lib" copy sqlite3.lib path\to\libs @@ -206,8 +211,86 @@ March 2012, --cc is not a valid option for pytest.py. However if you set an environment variable CC to the compliter exe, testing will use it. -.. _'mingw32 build': http://sourceforge.net/projects/mingw-w64/files/Toolchains%20targetting%20Win32/Automated%20Builds +.. _`mingw32 build`: http://sourceforge.net/projects/mingw-w64/files/Toolchains%20targetting%20Win32/Automated%20Builds .. _`mingw64 build`: http://sourceforge.net/projects/mingw-w64/files/Toolchains%20targetting%20Win64/Automated%20Builds .. _`msys for mingw`: http://sourceforge.net/projects/mingw-w64/files/External%20binary%20packages%20%28Win64%20hosted%29/MSYS%20%2832-bit%29 .. _`libffi source files`: http://sourceware.org/libffi/ .. _`RPython translation toolchain`: translation.html + + +What is missing for a full 64-bit translation +--------------------------------------------- + +The main blocker is that we assume that the integer type of RPython is +large enough to (occasionally) contain a pointer value cast to an +integer. The simplest fix is to make sure that it is so, but it will +give the following incompatibility between CPython and PyPy on Win64: + +CPython: ``sys.maxint == 2**32-1, sys.maxsize == 2**64-1`` + +PyPy: ``sys.maxint == sys.maxsize == 2**64-1`` + +...and, correspondingly, PyPy supports ints up to the larger value of +sys.maxint before they are converted to ``long``. The first decision +that someone needs to make is if this incompatibility is reasonable. + +Assuming that it is, the first thing to do is probably to hack *CPython* +until it fits this model: replace the field in PyIntObject with a ``long +long`` field, and change the value of ``sys.maxint``. This might just +work, even if half-brokenly: I'm sure you can crash it because of the +precision loss that undoubtedly occurs everywhere, but try not to. :-) + +Such a hacked CPython is what you'll use in the next steps. We'll call +it CPython64/64. + +It is probably not too much work if the goal is only to get a translated +PyPy executable, and to run all tests before transaction. But you need +to start somewhere, and you should start with some tests in +rpython/translator/c/test/, like ``test_standalone.py`` and +``test_newgc.py``: try to have them pass on top of CPython64/64. + +Keep in mind that this runs small translations, and some details may go +wrong. The most obvious one is to check that it produces C files that +use the integer type ``Signed`` --- but what is ``Signed`` defined to? +It should be equal to ``long`` on every other platforms, but on Win64 it +should be something like ``long long``. + +What is more generally needed is to review all the C files in +rpython/translator/c/src for the word ``long``, because this means a +32-bit integer even on Win64. Replace it with ``Signed`` most of the +times. You can replace one with the other without breaking anything on +any other platform, so feel free to. + +Then, these two C types have corresponding RPython types: ``rffi.LONG`` +and ``lltype.Signed`` respectively. The first should really correspond +to the C ``long``. Add tests that check that integers casted to one +type or the other really have 32 and 64 bits respectively, on Win64. + +Once these basic tests work, you need to review ``rpython/rlib/`` for +usages of ``rffi.LONG`` versus ``lltype.Signed``. The goal would be to +fix some more ``LONG-versus-Signed`` issues, by fixing the tests --- as +always run on top of CPython64/64. Note that there was some early work +done in ``rpython/rlib/rarithmetic`` with the goal of running all the +tests on Win64 on the regular CPython, but I think by now that it's a +bad idea. Look only at CPython64/64. + +The major intermediate goal is to get a translation of PyPy with ``-O2`` +with a minimal set of modules, starting with ``--no-allworkingmodules``; +you need to use CPython64/64 to run this translation too. Check +carefully the warnings of the C compiler at the end. I think that MSVC +is "nice" in the sense that by default a lot of mismatches of integer +sizes are reported as warnings. + +Then you need to review ``pypy/module/*/`` for ``LONG-versus-Signed`` +issues. At some time during this review, we get a working translated +PyPy on Windows 64 that includes all ``--translationmodules``, i.e. +everything needed to run translations. When we are there, the hacked +CPython64/64 becomes much less important, because we can run future +translations on top of this translated PyPy. As soon as we get there, +please *distribute* the translated PyPy. It's an essential component +for anyone else that wants to work on Win64! We end up with a strange +kind of dependency --- we need a translated PyPy in order to translate a +PyPy ---, but I believe it's ok here, as Windows executables are +supposed to never be broken by newer versions of Windows. + +Happy hacking :-) 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 @@ -119,13 +119,12 @@ except: try: stderr = sys.stderr - except AttributeError: - pass # too bad - else: print >> stderr, 'Error calling sys.excepthook:' originalexcepthook(*sys.exc_info()) print >> stderr print >> stderr, 'Original exception was:' + except: + pass # too bad # we only get here if sys.excepthook didn't do its job originalexcepthook(etype, evalue, etraceback) 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 @@ -982,9 +982,8 @@ return self._call_has_no_star_args(call) and not call.keywords def _optimize_method_call(self, call): - if not self.space.config.objspace.opcodes.CALL_METHOD or \ - not self._call_has_no_star_args(call) or \ - not isinstance(call.func, ast.Attribute): + if not self._call_has_no_star_args(call) or \ + not isinstance(call.func, ast.Attribute): return False attr_lookup = call.func assert isinstance(attr_lookup, ast.Attribute) diff --git a/pypy/interpreter/buffer.py b/pypy/interpreter/buffer.py --- a/pypy/interpreter/buffer.py +++ b/pypy/interpreter/buffer.py @@ -19,7 +19,7 @@ from pypy.interpreter.typedef import TypeDef from pypy.interpreter.gateway import interp2app, unwrap_spec from pypy.interpreter.error import OperationError -from rpython.rlib.objectmodel import compute_hash +from rpython.rlib.objectmodel import compute_hash, import_from_mixin from rpython.rlib.rstring import StringBuilder @@ -272,8 +272,6 @@ # ____________________________________________________________ class SubBufferMixin(object): - _mixin_ = True - def __init__(self, buffer, offset, size): self.buffer = buffer self.offset = offset @@ -297,10 +295,11 @@ # out of bounds return self.buffer.getslice(self.offset + start, self.offset + stop, step, size) -class SubBuffer(SubBufferMixin, Buffer): - pass +class SubBuffer(Buffer): + import_from_mixin(SubBufferMixin) -class RWSubBuffer(SubBufferMixin, RWBuffer): +class RWSubBuffer(RWBuffer): + import_from_mixin(SubBufferMixin) def setitem(self, index, char): self.buffer.setitem(self.offset + index, char) diff --git a/pypy/interpreter/pycode.py b/pypy/interpreter/pycode.py --- a/pypy/interpreter/pycode.py +++ b/pypy/interpreter/pycode.py @@ -251,8 +251,10 @@ tuple(self.co_cellvars)) def exec_host_bytecode(self, w_globals, w_locals): - from pypy.interpreter.pyframe import CPythonFrame - frame = CPythonFrame(self.space, self, w_globals, None) + if sys.version_info < (2, 7): + raise Exception("PyPy no longer supports Python 2.6 or lower") + from pypy.interpreter.pyframe import PyFrame + frame = self.space.FrameClass(self.space, self, w_globals, None) frame.setdictscope(w_locals) return frame.run() diff --git a/pypy/interpreter/pyframe.py b/pypy/interpreter/pyframe.py --- a/pypy/interpreter/pyframe.py +++ b/pypy/interpreter/pyframe.py @@ -52,7 +52,7 @@ def __init__(self, space, code, w_globals, outer_func): if not we_are_translated(): - assert type(self) in (space.FrameClass, CPythonFrame), ( + assert type(self) == space.FrameClass, ( "use space.FrameClass(), not directly PyFrame()") self = hint(self, access_directly=True, fresh_virtualizable=True) assert isinstance(code, pycode.PyCode) @@ -674,17 +674,6 @@ return space.wrap(self.builtin is not space.builtin) return space.w_False -class CPythonFrame(PyFrame): - """ - Execution of host (CPython) opcodes. - """ - - bytecode_spec = host_bytecode_spec - opcode_method_names = host_bytecode_spec.method_names - opcodedesc = host_bytecode_spec.opcodedesc - opdescmap = host_bytecode_spec.opdescmap - HAVE_ARGUMENT = host_bytecode_spec.HAVE_ARGUMENT - # ____________________________________________________________ diff --git a/pypy/interpreter/pyopcode.py b/pypy/interpreter/pyopcode.py --- a/pypy/interpreter/pyopcode.py +++ b/pypy/interpreter/pyopcode.py @@ -13,10 +13,8 @@ from rpython.rlib.objectmodel import we_are_translated from rpython.rlib import jit, rstackovf from rpython.rlib.rarithmetic import r_uint, intmask -from rpython.rlib.unroll import unrolling_iterable from rpython.rlib.debug import check_nonneg -from pypy.tool.stdlib_opcode import (bytecode_spec, - unrolling_all_opcode_descs) +from pypy.tool.stdlib_opcode import bytecode_spec def unaryoperation(operationname): """NOT_RPYTHON""" @@ -41,34 +39,14 @@ return func_with_new_name(opimpl, "opcode_impl_for_%s" % operationname) -compare_dispatch_table = [ - "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_dispatch_table)) - +opcodedesc = bytecode_spec.opcodedesc +HAVE_ARGUMENT = bytecode_spec.HAVE_ARGUMENT class __extend__(pyframe.PyFrame): """A PyFrame that knows about interpretation of standard Python opcodes minus the ones related to nested scopes.""" - bytecode_spec = bytecode_spec - opcode_method_names = bytecode_spec.method_names - opcodedesc = bytecode_spec.opcodedesc - opdescmap = bytecode_spec.opdescmap - HAVE_ARGUMENT = bytecode_spec.HAVE_ARGUMENT - ### opcode dispatch ### def dispatch(self, pycode, next_instr, ec): @@ -170,7 +148,7 @@ opcode = ord(co_code[next_instr]) next_instr += 1 - if opcode >= self.HAVE_ARGUMENT: + if opcode >= HAVE_ARGUMENT: lo = ord(co_code[next_instr]) hi = ord(co_code[next_instr+1]) next_instr += 2 @@ -180,19 +158,18 @@ # note: the structure of the code here is such that it makes # (after translation) a big "if/elif" chain, which is then - # turned into a switch(). It starts here: even if the first - # one is not an "if" but a "while" the effect is the same. + # turned into a switch(). - while opcode == self.opcodedesc.EXTENDED_ARG.index: + while opcode == opcodedesc.EXTENDED_ARG.index: opcode = ord(co_code[next_instr]) - if opcode < self.HAVE_ARGUMENT: + if opcode < HAVE_ARGUMENT: raise BytecodeCorruption lo = ord(co_code[next_instr+1]) hi = ord(co_code[next_instr+2]) next_instr += 3 oparg = (oparg * 65536) | (hi * 256) | lo - if opcode == self.opcodedesc.RETURN_VALUE.index: + if opcode == opcodedesc.RETURN_VALUE.index: w_returnvalue = self.popvalue() block = self.unrollstack(SReturnValue.kind) if block is None: @@ -202,8 +179,7 @@ unroller = SReturnValue(w_returnvalue) next_instr = block.handle(self, unroller) return next_instr # now inside a 'finally' block - - if opcode == self.opcodedesc.END_FINALLY.index: + elif opcode == opcodedesc.END_FINALLY.index: unroller = self.end_finally() if isinstance(unroller, SuspendedUnroller): # go on unrolling the stack @@ -215,49 +191,248 @@ else: next_instr = block.handle(self, unroller) return next_instr - - if opcode == self.opcodedesc.JUMP_ABSOLUTE.index: + elif opcode == opcodedesc.JUMP_ABSOLUTE.index: return self.jump_absolute(oparg, ec) - - if we_are_translated(): - for opdesc in unrolling_all_opcode_descs: - # static checks to skip this whole case if necessary - if opdesc.bytecode_spec is not self.bytecode_spec: - continue - if not opdesc.is_enabled(space): - continue - if opdesc.methodname in ( - 'EXTENDED_ARG', 'RETURN_VALUE', - 'END_FINALLY', 'JUMP_ABSOLUTE'): - continue # opcodes implemented above - - # the following "if" is part of the big switch described - # above. - if opcode == opdesc.index: - # dispatch to the opcode method - meth = getattr(self, opdesc.methodname) - res = meth(oparg, next_instr) - # !! warning, for the annotator the next line is not - # comparing an int and None - you can't do that. - # Instead, it's constant-folded to either True or False - if res is not None: - next_instr = res - break - else: - self.MISSING_OPCODE(oparg, next_instr) - - else: # when we are not translated, a list lookup is much faster - methodname = self.opcode_method_names[opcode] - try: - meth = getattr(self, methodname) - except AttributeError: - raise BytecodeCorruption("unimplemented opcode, ofs=%d, " - "code=%d, name=%s" % - (self.last_instr, opcode, - methodname)) - res = meth(oparg, next_instr) - if res is not None: - next_instr = res + elif opcode == opcodedesc.BREAK_LOOP.index: + next_instr = self.BREAK_LOOP(oparg, next_instr) + elif opcode == opcodedesc.CONTINUE_LOOP.index: + next_instr = self.CONTINUE_LOOP(oparg, next_instr) + elif opcode == opcodedesc.FOR_ITER.index: + next_instr = self.FOR_ITER(oparg, next_instr) + elif opcode == opcodedesc.JUMP_FORWARD.index: + next_instr = self.JUMP_FORWARD(oparg, next_instr) + elif opcode == opcodedesc.JUMP_IF_FALSE_OR_POP.index: + next_instr = self.JUMP_IF_FALSE_OR_POP(oparg, next_instr) + elif opcode == opcodedesc.JUMP_IF_NOT_DEBUG.index: + next_instr = self.JUMP_IF_NOT_DEBUG(oparg, next_instr) + elif opcode == opcodedesc.JUMP_IF_TRUE_OR_POP.index: + next_instr = self.JUMP_IF_TRUE_OR_POP(oparg, next_instr) + elif opcode == opcodedesc.POP_JUMP_IF_FALSE.index: + next_instr = self.POP_JUMP_IF_FALSE(oparg, next_instr) + elif opcode == opcodedesc.POP_JUMP_IF_TRUE.index: + next_instr = self.POP_JUMP_IF_TRUE(oparg, next_instr) + elif opcode == opcodedesc.BINARY_ADD.index: + self.BINARY_ADD(oparg, next_instr) + elif opcode == opcodedesc.BINARY_AND.index: + self.BINARY_AND(oparg, next_instr) + elif opcode == opcodedesc.BINARY_DIVIDE.index: + self.BINARY_DIVIDE(oparg, next_instr) + elif opcode == opcodedesc.BINARY_FLOOR_DIVIDE.index: + self.BINARY_FLOOR_DIVIDE(oparg, next_instr) + elif opcode == opcodedesc.BINARY_LSHIFT.index: + self.BINARY_LSHIFT(oparg, next_instr) + elif opcode == opcodedesc.BINARY_MODULO.index: + self.BINARY_MODULO(oparg, next_instr) + elif opcode == opcodedesc.BINARY_MULTIPLY.index: + self.BINARY_MULTIPLY(oparg, next_instr) + elif opcode == opcodedesc.BINARY_OR.index: + self.BINARY_OR(oparg, next_instr) + elif opcode == opcodedesc.BINARY_POWER.index: + self.BINARY_POWER(oparg, next_instr) + elif opcode == opcodedesc.BINARY_RSHIFT.index: + self.BINARY_RSHIFT(oparg, next_instr) + elif opcode == opcodedesc.BINARY_SUBSCR.index: + self.BINARY_SUBSCR(oparg, next_instr) + elif opcode == opcodedesc.BINARY_SUBTRACT.index: + self.BINARY_SUBTRACT(oparg, next_instr) + elif opcode == opcodedesc.BINARY_TRUE_DIVIDE.index: + self.BINARY_TRUE_DIVIDE(oparg, next_instr) + elif opcode == opcodedesc.BINARY_XOR.index: + self.BINARY_XOR(oparg, next_instr) + elif opcode == opcodedesc.BUILD_CLASS.index: + self.BUILD_CLASS(oparg, next_instr) + elif opcode == opcodedesc.BUILD_LIST.index: + self.BUILD_LIST(oparg, next_instr) + elif opcode == opcodedesc.BUILD_LIST_FROM_ARG.index: + self.BUILD_LIST_FROM_ARG(oparg, next_instr) + elif opcode == opcodedesc.BUILD_MAP.index: + self.BUILD_MAP(oparg, next_instr) + elif opcode == opcodedesc.BUILD_SET.index: + self.BUILD_SET(oparg, next_instr) + elif opcode == opcodedesc.BUILD_SLICE.index: + self.BUILD_SLICE(oparg, next_instr) + elif opcode == opcodedesc.BUILD_TUPLE.index: + self.BUILD_TUPLE(oparg, next_instr) + elif opcode == opcodedesc.CALL_FUNCTION.index: + self.CALL_FUNCTION(oparg, next_instr) + elif opcode == opcodedesc.CALL_FUNCTION_KW.index: + self.CALL_FUNCTION_KW(oparg, next_instr) + elif opcode == opcodedesc.CALL_FUNCTION_VAR.index: + self.CALL_FUNCTION_VAR(oparg, next_instr) + elif opcode == opcodedesc.CALL_FUNCTION_VAR_KW.index: + self.CALL_FUNCTION_VAR_KW(oparg, next_instr) + elif opcode == opcodedesc.CALL_METHOD.index: + self.CALL_METHOD(oparg, next_instr) + elif opcode == opcodedesc.COMPARE_OP.index: + self.COMPARE_OP(oparg, next_instr) + elif opcode == opcodedesc.DELETE_ATTR.index: + self.DELETE_ATTR(oparg, next_instr) + elif opcode == opcodedesc.DELETE_FAST.index: + self.DELETE_FAST(oparg, next_instr) + elif opcode == opcodedesc.DELETE_GLOBAL.index: + self.DELETE_GLOBAL(oparg, next_instr) + elif opcode == opcodedesc.DELETE_NAME.index: + self.DELETE_NAME(oparg, next_instr) + elif opcode == opcodedesc.DELETE_SLICE_0.index: + self.DELETE_SLICE_0(oparg, next_instr) + elif opcode == opcodedesc.DELETE_SLICE_1.index: + self.DELETE_SLICE_1(oparg, next_instr) + elif opcode == opcodedesc.DELETE_SLICE_2.index: + self.DELETE_SLICE_2(oparg, next_instr) + elif opcode == opcodedesc.DELETE_SLICE_3.index: + self.DELETE_SLICE_3(oparg, next_instr) + elif opcode == opcodedesc.DELETE_SUBSCR.index: + self.DELETE_SUBSCR(oparg, next_instr) + elif opcode == opcodedesc.DUP_TOP.index: + self.DUP_TOP(oparg, next_instr) + elif opcode == opcodedesc.DUP_TOPX.index: + self.DUP_TOPX(oparg, next_instr) + elif opcode == opcodedesc.EXEC_STMT.index: + self.EXEC_STMT(oparg, next_instr) + elif opcode == opcodedesc.GET_ITER.index: + self.GET_ITER(oparg, next_instr) + elif opcode == opcodedesc.IMPORT_FROM.index: + self.IMPORT_FROM(oparg, next_instr) + elif opcode == opcodedesc.IMPORT_NAME.index: + self.IMPORT_NAME(oparg, next_instr) + elif opcode == opcodedesc.IMPORT_STAR.index: + self.IMPORT_STAR(oparg, next_instr) + elif opcode == opcodedesc.INPLACE_ADD.index: + self.INPLACE_ADD(oparg, next_instr) + elif opcode == opcodedesc.INPLACE_AND.index: + self.INPLACE_AND(oparg, next_instr) + elif opcode == opcodedesc.INPLACE_DIVIDE.index: + self.INPLACE_DIVIDE(oparg, next_instr) + elif opcode == opcodedesc.INPLACE_FLOOR_DIVIDE.index: + self.INPLACE_FLOOR_DIVIDE(oparg, next_instr) + elif opcode == opcodedesc.INPLACE_LSHIFT.index: + self.INPLACE_LSHIFT(oparg, next_instr) + elif opcode == opcodedesc.INPLACE_MODULO.index: + self.INPLACE_MODULO(oparg, next_instr) + elif opcode == opcodedesc.INPLACE_MULTIPLY.index: + self.INPLACE_MULTIPLY(oparg, next_instr) + elif opcode == opcodedesc.INPLACE_OR.index: + self.INPLACE_OR(oparg, next_instr) + elif opcode == opcodedesc.INPLACE_POWER.index: + self.INPLACE_POWER(oparg, next_instr) + elif opcode == opcodedesc.INPLACE_RSHIFT.index: + self.INPLACE_RSHIFT(oparg, next_instr) + elif opcode == opcodedesc.INPLACE_SUBTRACT.index: + self.INPLACE_SUBTRACT(oparg, next_instr) + elif opcode == opcodedesc.INPLACE_TRUE_DIVIDE.index: + self.INPLACE_TRUE_DIVIDE(oparg, next_instr) + elif opcode == opcodedesc.INPLACE_XOR.index: + self.INPLACE_XOR(oparg, next_instr) + elif opcode == opcodedesc.LIST_APPEND.index: + self.LIST_APPEND(oparg, next_instr) + elif opcode == opcodedesc.LOAD_ATTR.index: + self.LOAD_ATTR(oparg, next_instr) + elif opcode == opcodedesc.LOAD_CLOSURE.index: + self.LOAD_CLOSURE(oparg, next_instr) + elif opcode == opcodedesc.LOAD_CONST.index: + self.LOAD_CONST(oparg, next_instr) + elif opcode == opcodedesc.LOAD_DEREF.index: + self.LOAD_DEREF(oparg, next_instr) + elif opcode == opcodedesc.LOAD_FAST.index: + self.LOAD_FAST(oparg, next_instr) + elif opcode == opcodedesc.LOAD_GLOBAL.index: + self.LOAD_GLOBAL(oparg, next_instr) + elif opcode == opcodedesc.LOAD_LOCALS.index: + self.LOAD_LOCALS(oparg, next_instr) + elif opcode == opcodedesc.LOAD_NAME.index: + self.LOAD_NAME(oparg, next_instr) + elif opcode == opcodedesc.LOOKUP_METHOD.index: + self.LOOKUP_METHOD(oparg, next_instr) + elif opcode == opcodedesc.MAKE_CLOSURE.index: + self.MAKE_CLOSURE(oparg, next_instr) + elif opcode == opcodedesc.MAKE_FUNCTION.index: + self.MAKE_FUNCTION(oparg, next_instr) + elif opcode == opcodedesc.MAP_ADD.index: + self.MAP_ADD(oparg, next_instr) + elif opcode == opcodedesc.NOP.index: + self.NOP(oparg, next_instr) + elif opcode == opcodedesc.POP_BLOCK.index: + self.POP_BLOCK(oparg, next_instr) + elif opcode == opcodedesc.POP_TOP.index: + self.POP_TOP(oparg, next_instr) + elif opcode == opcodedesc.PRINT_EXPR.index: + self.PRINT_EXPR(oparg, next_instr) + elif opcode == opcodedesc.PRINT_ITEM.index: + self.PRINT_ITEM(oparg, next_instr) + elif opcode == opcodedesc.PRINT_ITEM_TO.index: + self.PRINT_ITEM_TO(oparg, next_instr) + elif opcode == opcodedesc.PRINT_NEWLINE.index: + self.PRINT_NEWLINE(oparg, next_instr) + elif opcode == opcodedesc.PRINT_NEWLINE_TO.index: + self.PRINT_NEWLINE_TO(oparg, next_instr) + elif opcode == opcodedesc.RAISE_VARARGS.index: + self.RAISE_VARARGS(oparg, next_instr) + elif opcode == opcodedesc.ROT_FOUR.index: + self.ROT_FOUR(oparg, next_instr) + elif opcode == opcodedesc.ROT_THREE.index: + self.ROT_THREE(oparg, next_instr) + elif opcode == opcodedesc.ROT_TWO.index: + self.ROT_TWO(oparg, next_instr) + elif opcode == opcodedesc.SETUP_EXCEPT.index: + self.SETUP_EXCEPT(oparg, next_instr) + elif opcode == opcodedesc.SETUP_FINALLY.index: + self.SETUP_FINALLY(oparg, next_instr) + elif opcode == opcodedesc.SETUP_LOOP.index: + self.SETUP_LOOP(oparg, next_instr) + elif opcode == opcodedesc.SETUP_WITH.index: + self.SETUP_WITH(oparg, next_instr) + elif opcode == opcodedesc.SET_ADD.index: + self.SET_ADD(oparg, next_instr) + elif opcode == opcodedesc.SLICE_0.index: + self.SLICE_0(oparg, next_instr) + elif opcode == opcodedesc.SLICE_1.index: + self.SLICE_1(oparg, next_instr) + elif opcode == opcodedesc.SLICE_2.index: + self.SLICE_2(oparg, next_instr) + elif opcode == opcodedesc.SLICE_3.index: + self.SLICE_3(oparg, next_instr) + elif opcode == opcodedesc.STOP_CODE.index: + self.STOP_CODE(oparg, next_instr) + elif opcode == opcodedesc.STORE_ATTR.index: + self.STORE_ATTR(oparg, next_instr) + elif opcode == opcodedesc.STORE_DEREF.index: + self.STORE_DEREF(oparg, next_instr) + elif opcode == opcodedesc.STORE_FAST.index: + self.STORE_FAST(oparg, next_instr) + elif opcode == opcodedesc.STORE_GLOBAL.index: + self.STORE_GLOBAL(oparg, next_instr) + elif opcode == opcodedesc.STORE_MAP.index: + self.STORE_MAP(oparg, next_instr) + elif opcode == opcodedesc.STORE_NAME.index: + self.STORE_NAME(oparg, next_instr) + elif opcode == opcodedesc.STORE_SLICE_0.index: + self.STORE_SLICE_0(oparg, next_instr) + elif opcode == opcodedesc.STORE_SLICE_1.index: + self.STORE_SLICE_1(oparg, next_instr) + elif opcode == opcodedesc.STORE_SLICE_2.index: + self.STORE_SLICE_2(oparg, next_instr) + elif opcode == opcodedesc.STORE_SLICE_3.index: + self.STORE_SLICE_3(oparg, next_instr) + elif opcode == opcodedesc.STORE_SUBSCR.index: + self.STORE_SUBSCR(oparg, next_instr) + elif opcode == opcodedesc.UNARY_CONVERT.index: + self.UNARY_CONVERT(oparg, next_instr) + elif opcode == opcodedesc.UNARY_INVERT.index: + self.UNARY_INVERT(oparg, next_instr) + elif opcode == opcodedesc.UNARY_NEGATIVE.index: + self.UNARY_NEGATIVE(oparg, next_instr) + elif opcode == opcodedesc.UNARY_NOT.index: + self.UNARY_NOT(oparg, next_instr) + elif opcode == opcodedesc.UNARY_POSITIVE.index: + self.UNARY_POSITIVE(oparg, next_instr) + elif opcode == opcodedesc.UNPACK_SEQUENCE.index: + self.UNPACK_SEQUENCE(oparg, next_instr) + elif opcode == opcodedesc.WITH_CLEANUP.index: + self.WITH_CLEANUP(oparg, next_instr) + elif opcode == opcodedesc.YIELD_VALUE.index: + self.YIELD_VALUE(oparg, next_instr) + else: + self.MISSING_OPCODE(oparg, next_instr) if jit.we_are_jitted(): return next_instr @@ -733,36 +908,6 @@ self.pushvalue(w_value) LOAD_ATTR._always_inline_ = True - def cmp_lt(self, w_1, w_2): - return self.space.lt(w_1, w_2) - - def cmp_le(self, w_1, w_2): - return self.space.le(w_1, w_2) - - def cmp_eq(self, w_1, w_2): - return self.space.eq(w_1, w_2) - - def cmp_ne(self, w_1, w_2): - return self.space.ne(w_1, w_2) - - def cmp_gt(self, w_1, w_2): - return self.space.gt(w_1, w_2) - - def cmp_ge(self, w_1, w_2): - return self.space.ge(w_1, w_2) - - def cmp_in(self, w_1, w_2): - return self.space.contains(w_2, w_1) - - def cmp_not_in(self, w_1, w_2): - return self.space.not_(self.space.contains(w_2, w_1)) - - def cmp_is(self, w_1, w_2): - return self.space.is_(w_1, w_2) - - def cmp_is_not(self, w_1, w_2): - return self.space.not_(self.space.is_(w_1, w_2)) - @jit.unroll_safe def cmp_exc_match(self, w_1, w_2): space = self.space @@ -779,11 +924,28 @@ def COMPARE_OP(self, testnum, next_instr): w_2 = self.popvalue() w_1 = self.popvalue() - w_result = None - for i, attr in unrolling_compare_dispatch_table: - if i == testnum: - w_result = getattr(self, attr)(w_1, w_2) - break + if testnum == 0: + w_result = self.space.lt(w_1, w_2) + elif testnum == 1: + w_result = self.space.le(w_1, w_2) + elif testnum == 2: + w_result = self.space.eq(w_1, w_2) + elif testnum == 3: + w_result = self.space.ne(w_1, w_2) + elif testnum == 4: + w_result = self.space.gt(w_1, w_2) + elif testnum == 5: + w_result = self.space.ge(w_1, w_2) + elif testnum == 6: + w_result = self.space.contains(w_2, w_1) + elif testnum == 7: + w_result = self.space.not_(self.space.contains(w_2, w_1)) + elif testnum == 8: + w_result = self.space.is_(w_1, w_2) + elif testnum == 9: + w_result = self.space.not_(self.space.is_(w_1, w_2)) + elif testnum == 10: + w_result = self.cmp_exc_match(w_1, w_2) else: raise BytecodeCorruption("bad COMPARE_OP oparg") self.pushvalue(w_result) @@ -1086,49 +1248,6 @@ self.space.setitem(w_dict, w_key, w_value) -class __extend__(pyframe.CPythonFrame): - - def JUMP_IF_FALSE(self, stepby, next_instr): - w_cond = self.peekvalue() - if not self.space.is_true(w_cond): - next_instr += stepby - return next_instr - - def JUMP_IF_TRUE(self, stepby, next_instr): - w_cond = self.peekvalue() - if self.space.is_true(w_cond): - next_instr += stepby - return next_instr - - def BUILD_MAP(self, itemcount, next_instr): - if sys.version_info >= (2, 6): - # We could pre-allocate a dict here - # but for the moment this code is not translated. - pass - else: - if itemcount != 0: - raise BytecodeCorruption - w_dict = self.space.newdict() - self.pushvalue(w_dict) - - def STORE_MAP(self, zero, next_instr): - if sys.version_info >= (2, 6): - w_key = self.popvalue() - w_value = self.popvalue() - w_dict = self.peekvalue() - self.space.setitem(w_dict, w_key, w_value) - else: - raise BytecodeCorruption - - def LIST_APPEND(self, oparg, next_instr): - w = self.popvalue() - if sys.version_info < (2, 7): - v = self.popvalue() - else: - v = self.peekvalue(oparg - 1) - self.space.call_method(v, 'append', w) - - ### ____________________________________________________________ ### class ExitFrame(Exception): 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 @@ -953,10 +953,6 @@ assert i > -1 assert isinstance(co.co_consts[i], frozenset) - -class AppTestCallMethod(object): - spaceconfig = {'objspace.opcodes.CALL_METHOD': True} - def test_call_method_kwargs(self): source = """def _f(a): return a.f(a=a) diff --git a/pypy/interpreter/test/test_executioncontext.py b/pypy/interpreter/test/test_executioncontext.py --- a/pypy/interpreter/test/test_executioncontext.py +++ b/pypy/interpreter/test/test_executioncontext.py @@ -253,10 +253,6 @@ """) -class TestExecutionContextWithCallMethod(TestExecutionContext): - spaceconfig ={'objspace.opcodes.CALL_METHOD': True} - - class AppTestDelNotBlocked: def setup_method(self, meth): 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 @@ -812,10 +812,6 @@ assert len(called) == 1 assert isinstance(called[0], argument.Arguments) -class TestPassThroughArguments_CALL_METHOD(TestPassThroughArguments): - spaceconfig = dict(usemodules=('itertools',), **{ - "objspace.opcodes.CALL_METHOD": True - }) class AppTestKeywordsToBuiltinSanity(object): diff --git a/pypy/module/__pypy__/test/test_signal.py b/pypy/module/__pypy__/test/test_signal.py --- a/pypy/module/__pypy__/test/test_signal.py +++ b/pypy/module/__pypy__/test/test_signal.py @@ -34,7 +34,7 @@ thread.interrupt_main() for i in range(10): print('x') - time.sleep(0.1) + time.sleep(0.25) except BaseException, e: interrupted.append(e) finally: @@ -59,7 +59,7 @@ for j in range(10): if len(done): break print('.') - time.sleep(0.1) + time.sleep(0.25) print('main thread loop done') assert len(done) == 1 assert len(interrupted) == 1 @@ -117,7 +117,7 @@ def subthread(): try: - time.sleep(0.25) + time.sleep(0.5) with __pypy__.thread.signals_enabled: thread.interrupt_main() except BaseException, e: 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 @@ -1516,13 +1516,18 @@ d = BStruct.fields assert d[0][1].offset == d[1][1].offset == d[2][1].offset == 0 assert d[3][1].offset == sizeof(BLong) - assert d[0][1].bitshift == 0 + def f(m, r): + if sys.byteorder == 'little': + return r + else: + return LONGBITS - m - r + assert d[0][1].bitshift == f(1, 0) assert d[0][1].bitsize == 1 - assert d[1][1].bitshift == 1 + assert d[1][1].bitshift == f(2, 1) assert d[1][1].bitsize == 2 - assert d[2][1].bitshift == 3 + assert d[2][1].bitshift == f(3, 3) assert d[2][1].bitsize == 3 - assert d[3][1].bitshift == 0 + assert d[3][1].bitshift == f(LONGBITS - 5, 0) assert d[3][1].bitsize == LONGBITS - 5 assert sizeof(BStruct) == 2 * sizeof(BLong) assert alignof(BStruct) == alignof(BLong) @@ -2856,7 +2861,7 @@ ('b1', BInt, 9), ('b2', BUInt, 7), ('c', BChar, -1)], -1, -1, -1, flag) - if flag % 2 == 0: # gcc and gcc ARM + if flag % 2 == 0: # gcc, any variant assert typeoffsetof(BStruct, 'c') == (BChar, 3) assert sizeof(BStruct) == 4 else: # msvc @@ -2864,6 +2869,31 @@ assert sizeof(BStruct) == 12 assert alignof(BStruct) == 4 # + p = newp(new_pointer_type(BStruct), None) + p.a = b'A' + p.b1 = -201 + p.b2 = 99 + p.c = b'\x9D' + raw = buffer(p)[:] + if sys.byteorder == 'little': + if flag == 0 or flag == 2: # gcc, little endian + assert raw == b'A7\xC7\x9D' + elif flag == 1: # msvc + assert raw == b'A\x00\x00\x007\xC7\x00\x00\x9D\x00\x00\x00' + elif flag == 4: # gcc, big endian + assert raw == b'A\xE3\x9B\x9D' + else: + raise AssertionError("bad flag") + else: + if flag == 0 or flag == 2: # gcc + assert raw == b'A\xC77\x9D' + elif flag == 1: # msvc + assert raw == b'A\x00\x00\x00\x00\x00\xC77\x9D\x00\x00\x00' + elif flag == 4: # gcc, big endian + assert raw == b'A\x9B\xE3\x9D' + else: + raise AssertionError("bad flag") + # BStruct = new_struct_type("struct foo2") complete_struct_or_union(BStruct, [('a', BChar, -1), ('', BShort, 9), @@ -2875,16 +2905,21 @@ elif flag == 1: # msvc assert sizeof(BStruct) == 6 assert alignof(BStruct) == 2 - else: # gcc ARM + elif flag == 2: # gcc ARM assert sizeof(BStruct) == 6 assert alignof(BStruct) == 2 + elif flag == 4: # gcc, big endian + assert sizeof(BStruct) == 5 + assert alignof(BStruct) == 1 + else: + raise AssertionError("bad flag") # BStruct = new_struct_type("struct foo2") complete_struct_or_union(BStruct, [('a', BChar, -1), ('', BInt, 0), ('', BInt, 0), ('c', BChar, -1)], -1, -1, -1, flag) - if flag == 0: # gcc + if flag == 0: # gcc assert typeoffsetof(BStruct, 'c') == (BChar, 4) assert sizeof(BStruct) == 5 assert alignof(BStruct) == 1 @@ -2892,10 +2927,16 @@ assert typeoffsetof(BStruct, 'c') == (BChar, 1) assert sizeof(BStruct) == 2 assert alignof(BStruct) == 1 - else: # gcc ARM + elif flag == 2: # gcc ARM assert typeoffsetof(BStruct, 'c') == (BChar, 4) assert sizeof(BStruct) == 8 assert alignof(BStruct) == 4 + elif flag == 4: # gcc, big endian + assert typeoffsetof(BStruct, 'c') == (BChar, 4) + assert sizeof(BStruct) == 5 + assert alignof(BStruct) == 1 + else: + raise AssertionError("bad flag") def test_bitfield_as_gcc(): @@ -2907,6 +2948,11 @@ def test_bitfield_as_arm_gcc(): _test_bitfield_details(flag=2) +def test_bitfield_as_big_endian(): + if '__pypy__' in sys.builtin_module_names: + py.test.skip("no big endian machine supported on pypy for now") + _test_bitfield_details(flag=4) + def test_version(): # this test is here mostly for PyPy diff --git a/pypy/module/_continuation/interp_pickle.py b/pypy/module/_continuation/interp_pickle.py --- a/pypy/module/_continuation/interp_pickle.py +++ b/pypy/module/_continuation/interp_pickle.py @@ -120,8 +120,7 @@ nkwds = (oparg >> 8) & 0xff if nkwds == 0: # only positional arguments # fast paths leaves things on the stack, pop them - if (frame.space.config.objspace.opcodes.CALL_METHOD and - opcode == map['CALL_METHOD']): + if opcode == map['CALL_METHOD']: frame.dropvalues(nargs + 2) elif opcode == map['CALL_FUNCTION']: frame.dropvalues(nargs + 1) diff --git a/pypy/module/_continuation/test/test_zpickle.py b/pypy/module/_continuation/test/test_zpickle.py --- a/pypy/module/_continuation/test/test_zpickle.py +++ b/pypy/module/_continuation/test/test_zpickle.py @@ -1,8 +1,7 @@ class AppTestCopy: spaceconfig = dict(usemodules=['_continuation'], - continuation=True, - CALL_METHOD=True) + continuation=True) def test_basic_setup(self): from _continuation import continulet @@ -104,7 +103,6 @@ spaceconfig = { "usemodules": ['_continuation', 'struct', 'binascii'], "continuation": True, - "CALL_METHOD": True, } def setup_class(cls): 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 @@ -437,14 +437,14 @@ return self.getrepr(self.space, info) def getdisplayname(self): + space = self.space w_name = self.w_name if w_name is None: return '?' - elif self.space.is_true(self.space.isinstance(w_name, - self.space.w_str)): - return "'%s'" % self.space.str_w(w_name) + elif space.isinstance_w(w_name, space.w_str): + return "'%s'" % space.str_w(w_name) else: - return self.space.str_w(self.space.repr(w_name)) + return space.str_w(space.repr(w_name)) def file_writelines(self, w_lines): """writelines(sequence_of_strings) -> None. Write the strings to the file. diff --git a/pypy/module/_lsprof/test/test_cprofile.py b/pypy/module/_lsprof/test/test_cprofile.py --- a/pypy/module/_lsprof/test/test_cprofile.py +++ b/pypy/module/_lsprof/test/test_cprofile.py @@ -191,11 +191,6 @@ sys.path.pop(0) -class AppTestWithDifferentBytecodes(AppTestCProfile): - spaceconfig = AppTestCProfile.spaceconfig.copy() - spaceconfig['objspace.opcodes.CALL_METHOD'] = True - - expected_output = {} expected_output['print_stats'] = """\ 126 function calls (106 primitive calls) in 1.000 seconds 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 @@ -11,7 +11,7 @@ from rpython.rlib.unroll import unrolling_iterable from rpython.rlib.objectmodel import keepalive_until_here from rpython.rtyper.lltypesystem import lltype, rffi - +from pypy.objspace.std.floatobject import W_FloatObject @unwrap_spec(typecode=str) def w_array(space, w_cls, typecode, __args__): @@ -532,7 +532,7 @@ class TypeCode(object): - def __init__(self, itemtype, unwrap, canoverflow=False, signed=False): + def __init__(self, itemtype, unwrap, canoverflow=False, signed=False, method='__int__'): self.itemtype = itemtype self.bytes = rffi.sizeof(itemtype) self.arraytype = lltype.Array(itemtype, hints={'nolength': True}) @@ -540,6 +540,7 @@ self.signed = signed self.canoverflow = canoverflow self.w_class = None + self.method = method if self.canoverflow: assert self.bytes <= rffi.sizeof(rffi.ULONG) @@ -554,8 +555,8 @@ return True types = { - 'c': TypeCode(lltype.Char, 'str_w'), - 'u': TypeCode(lltype.UniChar, 'unicode_w'), + 'c': TypeCode(lltype.Char, 'str_w', method=''), + 'u': TypeCode(lltype.UniChar, 'unicode_w', method=''), 'b': TypeCode(rffi.SIGNEDCHAR, 'int_w', True, True), 'B': TypeCode(rffi.UCHAR, 'int_w', True), 'h': TypeCode(rffi.SHORT, 'int_w', True, True), @@ -567,8 +568,8 @@ # rbigint.touint() which # corresponds to the # C-type unsigned long - 'f': TypeCode(lltype.SingleFloat, 'float_w'), - 'd': TypeCode(lltype.Float, 'float_w'), + 'f': TypeCode(lltype.SingleFloat, 'float_w', method='__float__'), + 'd': TypeCode(lltype.Float, 'float_w', method='__float__'), } for k, v in types.items(): v.typecode = k @@ -613,7 +614,19 @@ def item_w(self, w_item): space = self.space unwrap = getattr(space, mytype.unwrap) - item = unwrap(w_item) + try: + item = unwrap(w_item) + except OperationError, e: + if isinstance(w_item, W_FloatObject): # Odd special case from cpython + raise + if mytype.method != '' and e.match(space, space.w_TypeError): + try: + item = unwrap(space.call_method(w_item, mytype.method)) + except OperationError: + msg = 'array item must be ' + mytype.unwrap[:-2] + raise OperationError(space.w_TypeError, space.wrap(msg)) + else: + raise if mytype.unwrap == 'bigint_w': try: item = item.touint() diff --git a/pypy/module/array/test/test_array.py b/pypy/module/array/test/test_array.py --- a/pypy/module/array/test/test_array.py +++ b/pypy/module/array/test/test_array.py @@ -874,6 +874,77 @@ assert l assert l[0] is None or len(l[0]) == 0 + def test_assign_object_with_special_methods(self): + from array import array + + class Num(object): + def __float__(self): + return 5.25 + + def __int__(self): + return 7 + + class NotNum(object): + pass + + class Silly(object): + def __float__(self): + return None + + def __int__(self): + return None + + class OldNum: + def __float__(self): + return 6.25 + + def __int__(self): + return 8 + + class OldNotNum: + pass + + class OldSilly: + def __float__(self): + return None + + def __int__(self): + return None + + for tc in 'bBhHiIlL': + a = array(tc, [0]) + raises(TypeError, a.__setitem__, 0, 1.0) + a[0] = 1 + a[0] = Num() + assert a[0] == 7 + raises(TypeError, a.__setitem__, NotNum()) + a[0] = OldNum() + assert a[0] == 8 + raises(TypeError, a.__setitem__, OldNotNum()) + raises(TypeError, a.__setitem__, Silly()) + raises(TypeError, a.__setitem__, OldSilly()) + + for tc in 'fd': + a = array(tc, [0]) + a[0] = 1.0 + a[0] = 1 + a[0] = Num() + assert a[0] == 5.25 + raises(TypeError, a.__setitem__, NotNum()) + a[0] = OldNum() + assert a[0] == 6.25 + raises(TypeError, a.__setitem__, OldNotNum()) + raises(TypeError, a.__setitem__, Silly()) + raises(TypeError, a.__setitem__, OldSilly()) + + a = array('c', 'hi') + a[0] = 'b' + assert a[0] == 'b' + + a = array('u', u'hi') + a[0] = u'b' + assert a[0] == u'b' + class TestCPythonsOwnArray(BaseArrayTests): 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 @@ -9,8 +9,8 @@ # the selection of the desired backend (default is Reflex). # choose C-API access method: -from pypy.module.cppyy.capi.loadable_capi import * -#from pypy.module.cppyy.capi.builtin_capi import * +#from pypy.module.cppyy.capi.loadable_capi import * +from pypy.module.cppyy.capi.builtin_capi import * from pypy.module.cppyy.capi.capi_types import C_OBJECT,\ C_NULL_TYPE, C_NULL_OBJECT diff --git a/pypy/module/cppyy/capi/builtin_capi.py b/pypy/module/cppyy/capi/builtin_capi.py --- a/pypy/module/cppyy/capi/builtin_capi.py +++ b/pypy/module/cppyy/capi/builtin_capi.py @@ -1,8 +1,8 @@ from rpython.rtyper.lltypesystem import rffi, lltype from rpython.rlib import jit -import reflex_capi as backend -#import cint_capi as backend +#import reflex_capi as backend +import cint_capi as backend from pypy.module.cppyy.capi.capi_types import C_SCOPE, C_TYPE, C_OBJECT,\ C_METHOD, C_INDEX, C_INDEX_ARRAY, WLAVC_INDEX,\ diff --git a/pypy/module/cpyext/pystate.py b/pypy/module/cpyext/pystate.py --- a/pypy/module/cpyext/pystate.py +++ b/pypy/module/cpyext/pystate.py @@ -241,7 +241,6 @@ it is necessary to serialize calls to this function.""" if not space.config.translation.thread: raise NoThreads - rthread.gc_thread_prepare() # PyThreadState_Get will allocate a new execution context, # we need to protect gc and other globals with the GIL. rffi.aroundstate.after() 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 @@ -841,8 +841,7 @@ # # default_magic - 6 -- used by CPython without the -U option # default_magic - 5 -- used by CPython with the -U option -# default_magic -- used by PyPy without the CALL_METHOD opcode -# default_magic + 2 -- used by PyPy with the CALL_METHOD opcode +# default_magic -- used by PyPy [because of CALL_METHOD] # from pypy.interpreter.pycode import default_magic MARSHAL_VERSION_FOR_PYC = 2 @@ -855,10 +854,7 @@ magic = __import__('imp').get_magic() return struct.unpack(' 1 and idx.get_shape() != self.get_shape(): raise OperationError(space.w_ValueError, space.wrap("boolean index array should have 1 dimension")) if idx.get_size() > self.get_size(): raise OperationError(space.w_ValueError, space.wrap("index out of range for array")) + idx_iter = idx.create_iter(self.get_shape()) + size = loop.count_all_true_iter(idx_iter, self.get_shape(), idx.get_dtype()) + if len(val.get_shape()) > 0 and val.get_shape()[0] > 1 and size > val.get_shape()[0]: + raise OperationError(space.w_ValueError, space.wrap("NumPy boolean array indexing assignment " + "cannot assign %d input values to " + "the %d output values where the mask is true" % (val.get_shape()[0],size))) + if val.get_shape() == [1]: + box = val.descr_getitem(space, space.wrap(0)) + assert isinstance(box, Box) + val = W_NDimArray(scalar.Scalar(val.get_dtype(), box)) + elif val.get_shape() == [0]: + val.implementation.dtype = self.implementation.dtype loop.setitem_filter(self, idx, val) def _prepare_array_index(self, space, w_index): 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 @@ -132,7 +132,7 @@ reduce_driver = jit.JitDriver(name='numpy_reduce', greens = ['shapelen', 'func', 'done_func', - 'calc_dtype', 'identity'], + 'calc_dtype'], reds = 'auto') def compute_reduce(obj, calc_dtype, func, done_func, identity): @@ -146,7 +146,7 @@ while not obj_iter.done(): reduce_driver.jit_merge_point(shapelen=shapelen, func=func, done_func=done_func, - calc_dtype=calc_dtype, identity=identity, + calc_dtype=calc_dtype, ) rval = obj_iter.getitem().convert_to(calc_dtype) if done_func is not None and done_func(calc_dtype, rval): @@ -318,23 +318,27 @@ lefti.next() return result -count_all_true_driver = jit.JitDriver(name = 'numpy_count', - greens = ['shapelen', 'dtype'], - reds = 'auto') def count_all_true(arr): - s = 0 if arr.is_scalar(): return arr.get_dtype().itemtype.bool(arr.get_scalar_value()) iter = arr.create_iter() - shapelen = len(arr.get_shape()) - dtype = arr.get_dtype() + return count_all_true_iter(iter, arr.get_shape(), arr.get_dtype()) + +count_all_true_iter_driver = jit.JitDriver(name = 'numpy_count', + greens = ['shapelen', 'dtype'], + reds = 'auto') +def count_all_true_iter(iter, shape, dtype): + s = 0 + shapelen = len(shape) + dtype = dtype while not iter.done(): - count_all_true_driver.jit_merge_point(shapelen=shapelen, dtype=dtype) + count_all_true_iter_driver.jit_merge_point(shapelen=shapelen, dtype=dtype) s += iter.getitem_bool() iter.next() return s + getitem_filter_driver = jit.JitDriver(name = 'numpy_getitem_bool', greens = ['shapelen', 'arr_dtype', 'index_dtype'], @@ -370,7 +374,7 @@ def setitem_filter(arr, index, value): arr_iter = arr.create_iter() - index_iter = index.create_iter() + index_iter = index.create_iter(arr.get_shape()) value_iter = value.create_iter() shapelen = len(arr.get_shape()) index_dtype = index.get_dtype() 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 @@ -685,3 +685,8 @@ msg=error_message) sys.stderr.write('.') sys.stderr.write('\n') + + def test_complexbox_to_pycomplex(self): + from numpypy import complex128 + x = complex128(3.4j) + assert complex(x) == 3.4j 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 @@ -778,6 +778,11 @@ from numpypy import unicode_ assert isinstance(unicode_(3), unicode) + def test_character_dtype(self): + from numpypy import array, character + x = array([["A", "B"], ["C", "D"]], character) + assert (x == [["A", "B"], ["C", "D"]]).all() + class AppTestRecordDtypes(BaseNumpyAppTest): spaceconfig = dict(usemodules=["micronumpy", "struct", "binascii"]) def test_create(self): 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 @@ -1922,6 +1922,29 @@ a = numpy.arange(10.).reshape((5, 2))[::2] assert (loads(dumps(a)) == a).all() + def test_string_filling(self): + import numpypy as numpy + a = numpy.empty((10,10), dtype='c1') + a.fill(12) + assert (a == '1').all() + + def test_boolean_indexing(self): + import numpypy as np + a = np.zeros((1, 3)) + b = np.array([True]) + + assert (a[b] == a).all() + + a[b] = 1. + + assert (a == [[1., 1., 1.]]).all() + + @py.test.mark.xfail + def test_boolean_array(self): + import numpypy as np + a = np.ndarray([1], dtype=bool) + assert a[0] == True + class AppTestMultiDim(BaseNumpyAppTest): def test_init(self): import numpypy @@ -2329,6 +2352,21 @@ a[a & 1 == 0] = 15 assert (a == [[15, 1], [15, 5], [15, 9]]).all() + def test_array_indexing_bool_specialcases(self): + from numpypy import arange, array + a = arange(6) + try: + a[a < 3] = [1, 2] + assert False, "Should not work" + except ValueError: + pass + a = arange(6) + a[a > 3] = array([15]) + assert (a == [0, 1, 2, 3, 15, 15]).all() + a = arange(6).reshape(3, 2) + a[a & 1 == 1] = [] # here, Numpy sticks garbage into the array + assert a.shape == (3, 2) + def test_copy_kwarg(self): from numpypy import array x = array([1, 2, 3]) diff --git a/pypy/module/micronumpy/test/test_ufuncs.py b/pypy/module/micronumpy/test/test_ufuncs.py --- a/pypy/module/micronumpy/test/test_ufuncs.py +++ b/pypy/module/micronumpy/test/test_ufuncs.py @@ -257,6 +257,7 @@ def test_rint(self): from numpypy import array, complex, rint, isnan + import sys nnan, nan, inf, ninf = float('-nan'), float('nan'), float('inf'), float('-inf') @@ -271,6 +272,8 @@ assert rint(complex(inf, 1.5)) == complex(inf, 2.) assert rint(complex(0.5, inf)) == complex(0., inf) + assert rint(sys.maxint) > 0.0 + def test_sign(self): from numpypy import array, sign, dtype diff --git a/pypy/module/micronumpy/test/test_zjit.py b/pypy/module/micronumpy/test/test_zjit.py --- a/pypy/module/micronumpy/test/test_zjit.py +++ b/pypy/module/micronumpy/test/test_zjit.py @@ -56,7 +56,7 @@ elif isinstance(w_res, interp_boxes.W_BoolBox): return float(w_res.value) raise TypeError(w_res) - + if self.graph is None: interp, graph = self.meta_interp(f, [0], listops=True, @@ -139,11 +139,17 @@ 'int_add': 3, }) + def define_reduce(): + return """ + a = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10] + sum(a) + """ + def test_reduce_compile_only_once(self): self.compile_graph() reset_stats() pyjitpl._warmrunnerdesc.memory_manager.alive_loops.clear() - i = self.code_mapping['sum'] + i = self.code_mapping['reduce'] # run it twice retval = self.interp.eval_graph(self.graph, [i]) retval = self.interp.eval_graph(self.graph, [i]) 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 @@ -308,13 +308,6 @@ return min(v1, v2) @simple_unary_op - def rint(self, v): - if isfinite(v): - return rfloat.round_double(v, 0, half_even=True) - else: - return v - - @simple_unary_op def ones_like(self, v): return 1 @@ -322,6 +315,10 @@ def zeros_like(self, v): return 0 + @raw_unary_op + def rint(self, v): + float64 = Float64() + return float64.rint(float64.box(v)) class NonNativePrimitive(Primitive): _mixin_ = True @@ -1036,6 +1033,25 @@ else: return v1 + v2 + @simple_unary_op + def rint(self, v): + x = float(v) + if isfinite(x): + import math + y = math.floor(x) + r = x - y + + if r > 0.5: + y += 1.0 + + if r == 0.5: + r = y - 2.0 * math.floor(0.5 * y) + if r == 1.0: + y += 1.0 + return y + else: + return x + class NonNativeFloat(NonNativePrimitive, Float): _mixin_ = True @@ -1748,12 +1764,16 @@ arr.storage[i] = arg[i] return interp_boxes.W_StringBox(arr, 0, arr.dtype) - @jit.unroll_safe def store(self, arr, i, offset, box): assert isinstance(box, interp_boxes.W_StringBox) # XXX simplify to range(box.dtype.get_size()) ? + return self._store(arr.storage, i, offset, box) + + @jit.unroll_safe + def _store(self, storage, i, offset, box): + 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] + storage[k + i] = box.arr.storage[k + offset] def read(self, arr, i, offset, dtype=None): if dtype is None: @@ -1843,6 +1863,11 @@ arr.storage[j] = '\x00' return interp_boxes.W_StringBox(arr, 0, arr.dtype) + def fill(self, storage, width, box, start, stop, offset): + from pypy.module.micronumpy.arrayimpl.concrete import ConcreteArrayNotOwning + for i in xrange(start, stop, width): + self._store(storage, i, offset, box) + NonNativeStringType = StringType class UnicodeType(BaseType, BaseStringType): 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 @@ -1,5 +1,3 @@ - -import py, sys from pypy.module.pypyjit.test_pypy_c.test_00_model import BaseTestPyPyC @@ -51,27 +49,6 @@ ... """) - def test_list(self): - def main(n): - i = 0 - while i < n: - z = list(()) - z.append(1) - i += z[-1] / len(z) - return i - - log = self.run(main, [1000]) - assert log.result == main(1000) - loop, = log.loops_by_filename(self.filepath) - assert loop.match(""" - i7 = int_lt(i5, i6) - guard_true(i7, descr=...) From noreply at buildbot.pypy.org Tue Sep 3 23:31:46 2013 From: noreply at buildbot.pypy.org (alex_gaynor) Date: Tue, 3 Sep 2013 23:31:46 +0200 (CEST) Subject: [pypy-commit] extradoc extradoc: Another item Message-ID: <20130903213146.4F79C1C135D@cobra.cs.uni-duesseldorf.de> Author: Alex Gaynor Branch: extradoc Changeset: r5046:fe4b71426b5d Date: 2013-09-03 14:31 -0700 http://bitbucket.org/pypy/extradoc/changeset/fe4b71426b5d/ Log: Another item diff --git a/planning/jit.txt b/planning/jit.txt --- a/planning/jit.txt +++ b/planning/jit.txt @@ -35,6 +35,16 @@ - ConstantFloat(0.0) should be generated with pxor %xmm, %xmm; instead of a movabs. +- Unroll some more dict methods, right now: + + d = {"a": 1, "b": 2, "c": 3, "d": 4, "e": 5} + + allocates a bunch of stuff just to call "dict_resize" + +- Heapcache in the metainterp needs to handle array of structs + (SETINTERIORFIELD, GETINTERIORFIELD). This is needed for the previous item to + fully work. + OPTIMIZATIONS ------------- From noreply at buildbot.pypy.org Wed Sep 4 01:03:04 2013 From: noreply at buildbot.pypy.org (alex_gaynor) Date: Wed, 4 Sep 2013 01:03:04 +0200 (CEST) Subject: [pypy-commit] pypy default: Enable inlining into the thread module so that Lock.acquire/release have a sane calling convention Message-ID: <20130903230304.866591C135D@cobra.cs.uni-duesseldorf.de> Author: Alex Gaynor Branch: Changeset: r66780:a3e9a5394648 Date: 2013-09-03 16:02 -0700 http://bitbucket.org/pypy/pypy/changeset/a3e9a5394648/ Log: Enable inlining into the thread module so that Lock.acquire/release have a sane calling convention 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 @@ -109,7 +109,8 @@ 'posix', '_socket', '_sre', '_lsprof', '_weakref', '__pypy__', 'cStringIO', '_collections', 'struct', 'mmap', 'marshal', '_codecs', 'rctime', 'cppyy', - '_cffi_backend', 'pyexpat', '_continuation', '_io']: + '_cffi_backend', 'pyexpat', '_continuation', '_io', + 'thread']: if modname == 'pypyjit' and 'interp_resop' in rest: return False return True diff --git a/pypy/module/pypyjit/test/test_policy.py b/pypy/module/pypyjit/test/test_policy.py --- a/pypy/module/pypyjit/test/test_policy.py +++ b/pypy/module/pypyjit/test/test_policy.py @@ -45,6 +45,10 @@ from pypy.module._io.interp_bytesio import W_BytesIO assert pypypolicy.look_inside_function(W_BytesIO.seek_w.im_func) +def test_thread(): + from pypy.module.thread.os_lock import Lock + assert pypypolicy.look_inside_function(Lock.descr_lock_acquire.im_func) + def test_pypy_module(): from pypy.module._collections.interp_deque import W_Deque from pypy.module._random.interp_random import W_Random From noreply at buildbot.pypy.org Wed Sep 4 09:45:50 2013 From: noreply at buildbot.pypy.org (bivab) Date: Wed, 4 Sep 2013 09:45:50 +0200 (CEST) Subject: [pypy-commit] buildbot default: restore CheckGotRevision step to keep the build naming and ordering Message-ID: <20130904074550.BF91D1C0205@cobra.cs.uni-duesseldorf.de> Author: David Schneider Branch: Changeset: r856:34a71026b5ae Date: 2013-09-04 09:45 +0200 http://bitbucket.org/pypy/buildbot/changeset/34a71026b5ae/ Log: restore CheckGotRevision step to keep the build naming and ordering diff --git a/bot2/pypybuildbot/builds.py b/bot2/pypybuildbot/builds.py --- a/bot2/pypybuildbot/builds.py +++ b/bot2/pypybuildbot/builds.py @@ -55,8 +55,8 @@ if not os.path.exists(masterdest): os.makedirs(masterdest) # - assert '%(got_revision)s' in self.basename - symname = self.basename.replace('%(got_revision)s', 'latest') + assert '%(final_file_name)s' in self.basename + symname = self.basename.replace('%(final_file_name)s', 'latest') assert '%' not in symname self.symlinkname = os.path.join(masterdest, symname) # @@ -168,6 +168,26 @@ builder.saveYourself() # _______________________________________________________________ +class CheckGotRevision(ShellCmd): + description = 'got_revision' + command = ['hg', 'parents', '--template', 'got_revision:{rev}:{node}'] + + def commandComplete(self, cmd): + if cmd.rc == 0: + got_revision = cmd.logs['stdio'].getText() + got_revision = got_revision.split('got_revision:')[-1] + # manually get the effect of {node|short} without using a + # '|' in the command-line, because it doesn't work on Windows + num = got_revision.find(':') + if num > 0: + got_revision = got_revision[:num + 13] + # + final_file_name = got_revision.replace(':', '-') + # ':' should not be part of filenames --- too many issues + self.build.setProperty('got_revision', got_revision, + 'got_revision') + self.build.setProperty('final_file_name', final_file_name, + 'got_revision') def update_hg(platform, factory, repourl, workdir, use_branch, force_branch=None): @@ -195,11 +215,12 @@ update_hg(platform, factory, repourl, workdir, use_branch=True, force_branch=force_branch) # + factory.addStep(CheckGotRevision(workdir=workdir)) def build_name(platform, jit=False, flags=[], placeholder=None): if placeholder is None: - placeholder = '%(got_revision)s' + placeholder = '%(final_file_name)s' if jit or '-Ojit' in flags: kind = 'jit' else: diff --git a/bot2/pypybuildbot/test/test_builds.py b/bot2/pypybuildbot/test/test_builds.py --- a/bot2/pypybuildbot/test/test_builds.py +++ b/bot2/pypybuildbot/test/test_builds.py @@ -62,7 +62,7 @@ def test_pypy_upload(): pth = py.test.ensuretemp('buildbot') inst = builds.PyPyUpload(slavesrc='slavesrc', masterdest=str(pth.join('mstr')), - basename='base-%(got_revision)s', workdir='.', + basename='base-%(final_file_name)s', workdir='.', blocksize=100) factory = inst._getStepFactory().factory kw = inst._getStepFactory().kwargs @@ -73,7 +73,7 @@ rebuilt.start() assert pth.join('mstr').check(dir=True) assert rebuilt.masterdest == str(pth.join('mstr', 'trunk', - 'base-123')) + 'base-123-ea5ca8')) assert rebuilt.symlinkname == str(pth.join('mstr', 'trunk', 'base-latest')) From noreply at buildbot.pypy.org Wed Sep 4 09:56:01 2013 From: noreply at buildbot.pypy.org (bivab) Date: Wed, 4 Sep 2013 09:56:01 +0200 (CEST) Subject: [pypy-commit] buildbot default: update benchmarks first, and then the pypy/cpython checkout Message-ID: <20130904075601.31DF71C0205@cobra.cs.uni-duesseldorf.de> Author: David Schneider Branch: Changeset: r857:96447497852a Date: 2013-09-04 09:55 +0200 http://bitbucket.org/pypy/buildbot/changeset/96447497852a/ Log: update benchmarks first, and then the pypy/cpython checkout diff --git a/bot2/pypybuildbot/builds.py b/bot2/pypybuildbot/builds.py --- a/bot2/pypybuildbot/builds.py +++ b/bot2/pypybuildbot/builds.py @@ -484,10 +484,11 @@ def __init__(self, platform='linux', host='tannit', postfix=''): factory.BuildFactory.__init__(self) - setup_steps(platform, self) # repourl = 'https://bitbucket.org/pypy/benchmarks' update_hg(platform, self, repourl, 'benchmarks', use_branch=False) + # + setup_steps(platform, self) if host == 'tannit': lock = TannitCPU elif host == 'speed_python': @@ -565,14 +566,14 @@ ''' factory.BuildFactory.__init__(self) + # check out and update benchmarks + repourl = 'https://bitbucket.org/pypy/benchmarks' + update_hg(platform, self, repourl, 'benchmarks', use_branch=False) + # checks out and updates the repo setup_steps(platform, self, repourl='http://hg.python.org/cpython', force_branch=branch) - # check out and update benchmarks - repourl = 'https://bitbucket.org/pypy/benchmarks' - update_hg(platform, self, repourl, 'benchmarks', use_branch=False) - lock = SpeedPythonCPU self.addStep(ShellCmd( From noreply at buildbot.pypy.org Wed Sep 4 13:13:32 2013 From: noreply at buildbot.pypy.org (Manuel Jacob) Date: Wed, 4 Sep 2013 13:13:32 +0200 (CEST) Subject: [pypy-commit] pypy refactor-translator: Remove fork_before option (unused). Message-ID: <20130904111332.C01451C135D@cobra.cs.uni-duesseldorf.de> Author: Manuel Jacob Branch: refactor-translator Changeset: r66781:57dd91f9ccd9 Date: 2013-09-02 18:08 +0100 http://bitbucket.org/pypy/pypy/changeset/57dd91f9ccd9/ Log: Remove fork_before option (unused). diff --git a/rpython/config/translationoption.py b/rpython/config/translationoption.py --- a/rpython/config/translationoption.py +++ b/rpython/config/translationoption.py @@ -127,11 +127,6 @@ default=False, cmdline=None), BoolOption("countmallocs", "Count mallocs and frees", default=False, cmdline=None), - ChoiceOption("fork_before", - "(UNIX) Create restartable checkpoint before step", - ["annotate", "rtype", "backendopt", "database", "source", - "pyjitpl"], - default=None, cmdline="--fork-before"), BoolOption("dont_write_c_files", "Make the C backend write everyting to /dev/null. " + "Useful for benchmarking, so you don't actually involve the disk", From noreply at buildbot.pypy.org Wed Sep 4 13:13:36 2013 From: noreply at buildbot.pypy.org (Manuel Jacob) Date: Wed, 4 Sep 2013 13:13:36 +0200 (CEST) Subject: [pypy-commit] pypy refactor-buffer-api: hg merge default Message-ID: <20130904111336.3811C1C135D@cobra.cs.uni-duesseldorf.de> Author: Manuel Jacob Branch: refactor-buffer-api Changeset: r66782:0ef9c7053ffd Date: 2013-09-03 01:16 +0100 http://bitbucket.org/pypy/pypy/changeset/0ef9c7053ffd/ Log: hg merge default diff too long, truncating to 2000 out of 4506 lines diff --git a/lib-python/2.7/uuid.py b/lib-python/2.7/uuid.py --- a/lib-python/2.7/uuid.py +++ b/lib-python/2.7/uuid.py @@ -127,26 +127,38 @@ overriding the given 'hex', 'bytes', 'bytes_le', 'fields', or 'int'. """ - if [hex, bytes, bytes_le, fields, int].count(None) != 4: - raise TypeError('need one of hex, bytes, bytes_le, fields, or int') if hex is not None: + if (bytes is not None or bytes_le is not None or fields is not None + or int is not None): + raise TypeError('if the hex argument is given, bytes, bytes_le, fields,' + ' and int need to be None') hex = hex.replace('urn:', '').replace('uuid:', '') hex = hex.strip('{}').replace('-', '') if len(hex) != 32: raise ValueError('badly formed hexadecimal UUID string') int = long(hex, 16) - if bytes_le is not None: + elif bytes_le is not None: + if bytes is not None or fields is not None or int is not None: + raise TypeError('if the bytes_le argument is given, bytes, fields,' + ' and int need to be None') if len(bytes_le) != 16: raise ValueError('bytes_le is not a 16-char string') bytes = (bytes_le[3] + bytes_le[2] + bytes_le[1] + bytes_le[0] + bytes_le[5] + bytes_le[4] + bytes_le[7] + bytes_le[6] + bytes_le[8:]) - if bytes is not None: + int = (struct.unpack('>Q', bytes[:8])[0] << 64 | + struct.unpack('>Q', bytes[8:])[0]) + elif bytes is not None: + if fields is not None or int is not None: + raise TypeError('if the bytes argument is given, fields' + ' and int need to be None') if len(bytes) != 16: raise ValueError('bytes is not a 16-char string') int = (struct.unpack('>Q', bytes[:8])[0] << 64 | struct.unpack('>Q', bytes[8:])[0]) - if fields is not None: + elif fields is not None: + if int is not None: + raise TypeError('if the fields argument is given, int needs to be None') if len(fields) != 6: raise ValueError('fields is not a 6-tuple') (time_low, time_mid, time_hi_version, @@ -166,9 +178,12 @@ clock_seq = (clock_seq_hi_variant << 8L) | clock_seq_low int = ((time_low << 96L) | (time_mid << 80L) | (time_hi_version << 64L) | (clock_seq << 48L) | node) - if int is not None: + elif int is not None: if not 0 <= int < 1<<128L: raise ValueError('int is out of range (need a 128-bit value)') + else: + raise TypeError('one of hex, bytes, bytes_le, fields,' + ' or int need to be not None') if version is not None: if not 1 <= version <= 5: raise ValueError('illegal version number') @@ -178,7 +193,7 @@ # Set the version number. int &= ~(0xf000 << 64L) int |= version << 76L - self.__dict__['int'] = int + object.__setattr__(self, 'int', int) def __cmp__(self, other): if isinstance(other, UUID): diff --git a/lib_pypy/_curses.py b/lib_pypy/_curses.py --- a/lib_pypy/_curses.py +++ b/lib_pypy/_curses.py @@ -1,6 +1,9 @@ """Reimplementation of the standard extension module '_curses' using cffi.""" import sys +if sys.platform == 'win32': + #This module does not exist in windows + raise ImportError('No module named _curses') from functools import wraps from cffi import FFI diff --git a/pypy/config/pypyoption.py b/pypy/config/pypyoption.py --- a/pypy/config/pypyoption.py +++ b/pypy/config/pypyoption.py @@ -127,11 +127,6 @@ pypy_optiondescription = OptionDescription("objspace", "Object Space Options", [ - OptionDescription("opcodes", "opcodes to enable in the interpreter", [ - BoolOption("CALL_METHOD", "emit a special bytecode for expr.name()", - default=False), - ]), - OptionDescription("usemodules", "Which Modules should be used", [ BoolOption(modname, "use module %s" % (modname, ), default=modname in default_modules, @@ -259,9 +254,6 @@ BoolOption("optimized_int_add", "special case the addition of two integers in BINARY_ADD", default=False), - BoolOption("optimized_comparison_op", - "special case the comparison of integers", - default=False), BoolOption("optimized_list_getitem", "special case the 'list[integer]' expressions", default=False), @@ -307,7 +299,6 @@ # all the good optimizations for PyPy should be listed here if level in ['2', '3', 'jit']: - config.objspace.opcodes.suggest(CALL_METHOD=True) config.objspace.std.suggest(withrangelist=True) config.objspace.std.suggest(withmethodcache=True) config.objspace.std.suggest(withprebuiltchar=True) diff --git a/pypy/doc/config/objspace.opcodes.CALL_METHOD.txt b/pypy/doc/config/objspace.opcodes.CALL_METHOD.txt deleted file mode 100644 --- a/pypy/doc/config/objspace.opcodes.CALL_METHOD.txt +++ /dev/null @@ -1,10 +0,0 @@ -Enable a pair of bytecodes that speed up method calls. -See ``pypy.interpreter.callmethod`` for a description. - -The goal is to avoid creating the bound method object in the common -case. So far, this only works for calls with no keyword, no ``*arg`` -and no ``**arg`` but it would be easy to extend. - -For more information, see the section in `Standard Interpreter Optimizations`_. - -.. _`Standard Interpreter Optimizations`: ../interpreter-optimizations.html#lookup-method-call-method diff --git a/pypy/doc/config/objspace.opcodes.txt b/pypy/doc/config/objspace.opcodes.txt deleted file mode 100644 --- a/pypy/doc/config/objspace.opcodes.txt +++ /dev/null @@ -1,1 +0,0 @@ -.. intentionally empty 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 @@ -198,9 +198,6 @@ if it is not None, then it is considered to be an additional first argument in the call to the *im_func* object from the stack. -You can enable this feature with the :config:`objspace.opcodes.CALL_METHOD` -option. - .. more here? Overall Effects diff --git a/pypy/doc/tool/makecontributor.py b/pypy/doc/tool/makecontributor.py --- a/pypy/doc/tool/makecontributor.py +++ b/pypy/doc/tool/makecontributor.py @@ -60,6 +60,11 @@ 'Roberto De Ioris': ['roberto at mrspurr'], 'Sven Hager': ['hager'], 'Tomo Cocoa': ['cocoatomo'], + 'Romain Guillebert': ['rguillebert', 'rguillbert', 'romain', 'Guillebert Romain'], + 'Ronan Lamy': ['ronan'], + 'Edd Barrett': ['edd'], + 'Manuel Jacob': ['mjacob'], + 'Rami Chowdhury': ['necaris'], } alias_map = {} @@ -80,7 +85,8 @@ if not match: return set() ignore_words = ['around', 'consulting', 'yesterday', 'for a bit', 'thanks', - 'in-progress', 'bits of', 'even a little', 'floating',] + 'in-progress', 'bits of', 'even a little', 'floating', + 'a bit', 'reviewing'] sep_words = ['and', ';', '+', '/', 'with special by'] nicknames = match.group(1) for word in ignore_words: @@ -119,7 +125,7 @@ ## print '%5d %s' % (n, name) ## else: ## print name - + items = authors_count.items() items.sort(key=operator.itemgetter(1), reverse=True) for name, n in items: 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 @@ -5,6 +5,11 @@ .. this is a revision shortly after release-2.1-beta .. startrev: 4eb52818e7c0 +.. branch: sanitise_bytecode_dispatch +Make PyPy's bytecode dispatcher easy to read, and less reliant on RPython +magic. There is no functional change, though the removal of dead code leads +to many fewer tests to execute. + .. branch: fastjson Fast json decoder written in RPython, about 3-4x faster than the pure Python decoder which comes with the stdlib @@ -75,3 +80,17 @@ .. branch: reflex-support .. branch: numpypy-inplace-op .. branch: rewritten-loop-logging + +.. branch: nobold-backtrace +Work on improving UnionError messages and stack trace displays. + +.. branch: improve-errors-again +More improvements and refactorings of error messages. + +.. branch: improve-errors-again2 +Unbreak tests in rlib. + +.. branch: less-stringly-ops +Use subclasses of SpaceOperation instead of SpaceOperator objects. +Random cleanups in flowspace. + 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 @@ -982,9 +982,8 @@ return self._call_has_no_star_args(call) and not call.keywords def _optimize_method_call(self, call): - if not self.space.config.objspace.opcodes.CALL_METHOD or \ - not self._call_has_no_star_args(call) or \ - not isinstance(call.func, ast.Attribute): + if not self._call_has_no_star_args(call) or \ + not isinstance(call.func, ast.Attribute): return False attr_lookup = call.func assert isinstance(attr_lookup, ast.Attribute) diff --git a/pypy/interpreter/pycode.py b/pypy/interpreter/pycode.py --- a/pypy/interpreter/pycode.py +++ b/pypy/interpreter/pycode.py @@ -251,8 +251,10 @@ tuple(self.co_cellvars)) def exec_host_bytecode(self, w_globals, w_locals): - from pypy.interpreter.pyframe import CPythonFrame - frame = CPythonFrame(self.space, self, w_globals, None) + if sys.version_info < (2, 7): + raise Exception("PyPy no longer supports Python 2.6 or lower") + from pypy.interpreter.pyframe import PyFrame + frame = self.space.FrameClass(self.space, self, w_globals, None) frame.setdictscope(w_locals) return frame.run() diff --git a/pypy/interpreter/pyframe.py b/pypy/interpreter/pyframe.py --- a/pypy/interpreter/pyframe.py +++ b/pypy/interpreter/pyframe.py @@ -52,7 +52,7 @@ def __init__(self, space, code, w_globals, outer_func): if not we_are_translated(): - assert type(self) in (space.FrameClass, CPythonFrame), ( + assert type(self) == space.FrameClass, ( "use space.FrameClass(), not directly PyFrame()") self = hint(self, access_directly=True, fresh_virtualizable=True) assert isinstance(code, pycode.PyCode) @@ -674,17 +674,6 @@ return space.wrap(self.builtin is not space.builtin) return space.w_False -class CPythonFrame(PyFrame): - """ - Execution of host (CPython) opcodes. - """ - - bytecode_spec = host_bytecode_spec - opcode_method_names = host_bytecode_spec.method_names - opcodedesc = host_bytecode_spec.opcodedesc - opdescmap = host_bytecode_spec.opdescmap - HAVE_ARGUMENT = host_bytecode_spec.HAVE_ARGUMENT - # ____________________________________________________________ diff --git a/pypy/interpreter/pyopcode.py b/pypy/interpreter/pyopcode.py --- a/pypy/interpreter/pyopcode.py +++ b/pypy/interpreter/pyopcode.py @@ -13,10 +13,8 @@ from rpython.rlib.objectmodel import we_are_translated from rpython.rlib import jit, rstackovf from rpython.rlib.rarithmetic import r_uint, intmask -from rpython.rlib.unroll import unrolling_iterable from rpython.rlib.debug import check_nonneg -from pypy.tool.stdlib_opcode import (bytecode_spec, - unrolling_all_opcode_descs) +from pypy.tool.stdlib_opcode import bytecode_spec def unaryoperation(operationname): """NOT_RPYTHON""" @@ -41,34 +39,14 @@ return func_with_new_name(opimpl, "opcode_impl_for_%s" % operationname) -compare_dispatch_table = [ - "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_dispatch_table)) - +opcodedesc = bytecode_spec.opcodedesc +HAVE_ARGUMENT = bytecode_spec.HAVE_ARGUMENT class __extend__(pyframe.PyFrame): """A PyFrame that knows about interpretation of standard Python opcodes minus the ones related to nested scopes.""" - bytecode_spec = bytecode_spec - opcode_method_names = bytecode_spec.method_names - opcodedesc = bytecode_spec.opcodedesc - opdescmap = bytecode_spec.opdescmap - HAVE_ARGUMENT = bytecode_spec.HAVE_ARGUMENT - ### opcode dispatch ### def dispatch(self, pycode, next_instr, ec): @@ -170,7 +148,7 @@ opcode = ord(co_code[next_instr]) next_instr += 1 - if opcode >= self.HAVE_ARGUMENT: + if opcode >= HAVE_ARGUMENT: lo = ord(co_code[next_instr]) hi = ord(co_code[next_instr+1]) next_instr += 2 @@ -180,19 +158,18 @@ # note: the structure of the code here is such that it makes # (after translation) a big "if/elif" chain, which is then - # turned into a switch(). It starts here: even if the first - # one is not an "if" but a "while" the effect is the same. + # turned into a switch(). - while opcode == self.opcodedesc.EXTENDED_ARG.index: + while opcode == opcodedesc.EXTENDED_ARG.index: opcode = ord(co_code[next_instr]) - if opcode < self.HAVE_ARGUMENT: + if opcode < HAVE_ARGUMENT: raise BytecodeCorruption lo = ord(co_code[next_instr+1]) hi = ord(co_code[next_instr+2]) next_instr += 3 oparg = (oparg * 65536) | (hi * 256) | lo - if opcode == self.opcodedesc.RETURN_VALUE.index: + if opcode == opcodedesc.RETURN_VALUE.index: w_returnvalue = self.popvalue() block = self.unrollstack(SReturnValue.kind) if block is None: @@ -202,8 +179,7 @@ unroller = SReturnValue(w_returnvalue) next_instr = block.handle(self, unroller) return next_instr # now inside a 'finally' block - - if opcode == self.opcodedesc.END_FINALLY.index: + elif opcode == opcodedesc.END_FINALLY.index: unroller = self.end_finally() if isinstance(unroller, SuspendedUnroller): # go on unrolling the stack @@ -215,49 +191,248 @@ else: next_instr = block.handle(self, unroller) return next_instr - - if opcode == self.opcodedesc.JUMP_ABSOLUTE.index: + elif opcode == opcodedesc.JUMP_ABSOLUTE.index: return self.jump_absolute(oparg, ec) - - if we_are_translated(): - for opdesc in unrolling_all_opcode_descs: - # static checks to skip this whole case if necessary - if opdesc.bytecode_spec is not self.bytecode_spec: - continue - if not opdesc.is_enabled(space): - continue - if opdesc.methodname in ( - 'EXTENDED_ARG', 'RETURN_VALUE', - 'END_FINALLY', 'JUMP_ABSOLUTE'): - continue # opcodes implemented above - - # the following "if" is part of the big switch described - # above. - if opcode == opdesc.index: - # dispatch to the opcode method - meth = getattr(self, opdesc.methodname) - res = meth(oparg, next_instr) - # !! warning, for the annotator the next line is not - # comparing an int and None - you can't do that. - # Instead, it's constant-folded to either True or False - if res is not None: - next_instr = res - break - else: - self.MISSING_OPCODE(oparg, next_instr) - - else: # when we are not translated, a list lookup is much faster - methodname = self.opcode_method_names[opcode] - try: - meth = getattr(self, methodname) - except AttributeError: - raise BytecodeCorruption("unimplemented opcode, ofs=%d, " - "code=%d, name=%s" % - (self.last_instr, opcode, - methodname)) - res = meth(oparg, next_instr) - if res is not None: - next_instr = res + elif opcode == opcodedesc.BREAK_LOOP.index: + next_instr = self.BREAK_LOOP(oparg, next_instr) + elif opcode == opcodedesc.CONTINUE_LOOP.index: + next_instr = self.CONTINUE_LOOP(oparg, next_instr) + elif opcode == opcodedesc.FOR_ITER.index: + next_instr = self.FOR_ITER(oparg, next_instr) + elif opcode == opcodedesc.JUMP_FORWARD.index: + next_instr = self.JUMP_FORWARD(oparg, next_instr) + elif opcode == opcodedesc.JUMP_IF_FALSE_OR_POP.index: + next_instr = self.JUMP_IF_FALSE_OR_POP(oparg, next_instr) + elif opcode == opcodedesc.JUMP_IF_NOT_DEBUG.index: + next_instr = self.JUMP_IF_NOT_DEBUG(oparg, next_instr) + elif opcode == opcodedesc.JUMP_IF_TRUE_OR_POP.index: + next_instr = self.JUMP_IF_TRUE_OR_POP(oparg, next_instr) + elif opcode == opcodedesc.POP_JUMP_IF_FALSE.index: + next_instr = self.POP_JUMP_IF_FALSE(oparg, next_instr) + elif opcode == opcodedesc.POP_JUMP_IF_TRUE.index: + next_instr = self.POP_JUMP_IF_TRUE(oparg, next_instr) + elif opcode == opcodedesc.BINARY_ADD.index: + self.BINARY_ADD(oparg, next_instr) + elif opcode == opcodedesc.BINARY_AND.index: + self.BINARY_AND(oparg, next_instr) + elif opcode == opcodedesc.BINARY_DIVIDE.index: + self.BINARY_DIVIDE(oparg, next_instr) + elif opcode == opcodedesc.BINARY_FLOOR_DIVIDE.index: + self.BINARY_FLOOR_DIVIDE(oparg, next_instr) + elif opcode == opcodedesc.BINARY_LSHIFT.index: + self.BINARY_LSHIFT(oparg, next_instr) + elif opcode == opcodedesc.BINARY_MODULO.index: + self.BINARY_MODULO(oparg, next_instr) + elif opcode == opcodedesc.BINARY_MULTIPLY.index: + self.BINARY_MULTIPLY(oparg, next_instr) + elif opcode == opcodedesc.BINARY_OR.index: + self.BINARY_OR(oparg, next_instr) + elif opcode == opcodedesc.BINARY_POWER.index: + self.BINARY_POWER(oparg, next_instr) + elif opcode == opcodedesc.BINARY_RSHIFT.index: + self.BINARY_RSHIFT(oparg, next_instr) + elif opcode == opcodedesc.BINARY_SUBSCR.index: + self.BINARY_SUBSCR(oparg, next_instr) + elif opcode == opcodedesc.BINARY_SUBTRACT.index: + self.BINARY_SUBTRACT(oparg, next_instr) + elif opcode == opcodedesc.BINARY_TRUE_DIVIDE.index: + self.BINARY_TRUE_DIVIDE(oparg, next_instr) + elif opcode == opcodedesc.BINARY_XOR.index: + self.BINARY_XOR(oparg, next_instr) + elif opcode == opcodedesc.BUILD_CLASS.index: + self.BUILD_CLASS(oparg, next_instr) + elif opcode == opcodedesc.BUILD_LIST.index: + self.BUILD_LIST(oparg, next_instr) + elif opcode == opcodedesc.BUILD_LIST_FROM_ARG.index: + self.BUILD_LIST_FROM_ARG(oparg, next_instr) + elif opcode == opcodedesc.BUILD_MAP.index: + self.BUILD_MAP(oparg, next_instr) + elif opcode == opcodedesc.BUILD_SET.index: + self.BUILD_SET(oparg, next_instr) + elif opcode == opcodedesc.BUILD_SLICE.index: + self.BUILD_SLICE(oparg, next_instr) + elif opcode == opcodedesc.BUILD_TUPLE.index: + self.BUILD_TUPLE(oparg, next_instr) + elif opcode == opcodedesc.CALL_FUNCTION.index: + self.CALL_FUNCTION(oparg, next_instr) + elif opcode == opcodedesc.CALL_FUNCTION_KW.index: + self.CALL_FUNCTION_KW(oparg, next_instr) + elif opcode == opcodedesc.CALL_FUNCTION_VAR.index: + self.CALL_FUNCTION_VAR(oparg, next_instr) + elif opcode == opcodedesc.CALL_FUNCTION_VAR_KW.index: + self.CALL_FUNCTION_VAR_KW(oparg, next_instr) + elif opcode == opcodedesc.CALL_METHOD.index: + self.CALL_METHOD(oparg, next_instr) + elif opcode == opcodedesc.COMPARE_OP.index: + self.COMPARE_OP(oparg, next_instr) + elif opcode == opcodedesc.DELETE_ATTR.index: + self.DELETE_ATTR(oparg, next_instr) + elif opcode == opcodedesc.DELETE_FAST.index: + self.DELETE_FAST(oparg, next_instr) + elif opcode == opcodedesc.DELETE_GLOBAL.index: + self.DELETE_GLOBAL(oparg, next_instr) + elif opcode == opcodedesc.DELETE_NAME.index: + self.DELETE_NAME(oparg, next_instr) + elif opcode == opcodedesc.DELETE_SLICE_0.index: + self.DELETE_SLICE_0(oparg, next_instr) + elif opcode == opcodedesc.DELETE_SLICE_1.index: + self.DELETE_SLICE_1(oparg, next_instr) + elif opcode == opcodedesc.DELETE_SLICE_2.index: + self.DELETE_SLICE_2(oparg, next_instr) + elif opcode == opcodedesc.DELETE_SLICE_3.index: + self.DELETE_SLICE_3(oparg, next_instr) + elif opcode == opcodedesc.DELETE_SUBSCR.index: + self.DELETE_SUBSCR(oparg, next_instr) + elif opcode == opcodedesc.DUP_TOP.index: + self.DUP_TOP(oparg, next_instr) + elif opcode == opcodedesc.DUP_TOPX.index: + self.DUP_TOPX(oparg, next_instr) + elif opcode == opcodedesc.EXEC_STMT.index: + self.EXEC_STMT(oparg, next_instr) + elif opcode == opcodedesc.GET_ITER.index: + self.GET_ITER(oparg, next_instr) + elif opcode == opcodedesc.IMPORT_FROM.index: + self.IMPORT_FROM(oparg, next_instr) + elif opcode == opcodedesc.IMPORT_NAME.index: + self.IMPORT_NAME(oparg, next_instr) + elif opcode == opcodedesc.IMPORT_STAR.index: + self.IMPORT_STAR(oparg, next_instr) + elif opcode == opcodedesc.INPLACE_ADD.index: + self.INPLACE_ADD(oparg, next_instr) + elif opcode == opcodedesc.INPLACE_AND.index: + self.INPLACE_AND(oparg, next_instr) + elif opcode == opcodedesc.INPLACE_DIVIDE.index: + self.INPLACE_DIVIDE(oparg, next_instr) + elif opcode == opcodedesc.INPLACE_FLOOR_DIVIDE.index: + self.INPLACE_FLOOR_DIVIDE(oparg, next_instr) + elif opcode == opcodedesc.INPLACE_LSHIFT.index: + self.INPLACE_LSHIFT(oparg, next_instr) + elif opcode == opcodedesc.INPLACE_MODULO.index: + self.INPLACE_MODULO(oparg, next_instr) + elif opcode == opcodedesc.INPLACE_MULTIPLY.index: + self.INPLACE_MULTIPLY(oparg, next_instr) + elif opcode == opcodedesc.INPLACE_OR.index: + self.INPLACE_OR(oparg, next_instr) + elif opcode == opcodedesc.INPLACE_POWER.index: + self.INPLACE_POWER(oparg, next_instr) + elif opcode == opcodedesc.INPLACE_RSHIFT.index: + self.INPLACE_RSHIFT(oparg, next_instr) + elif opcode == opcodedesc.INPLACE_SUBTRACT.index: + self.INPLACE_SUBTRACT(oparg, next_instr) + elif opcode == opcodedesc.INPLACE_TRUE_DIVIDE.index: + self.INPLACE_TRUE_DIVIDE(oparg, next_instr) + elif opcode == opcodedesc.INPLACE_XOR.index: + self.INPLACE_XOR(oparg, next_instr) + elif opcode == opcodedesc.LIST_APPEND.index: + self.LIST_APPEND(oparg, next_instr) + elif opcode == opcodedesc.LOAD_ATTR.index: + self.LOAD_ATTR(oparg, next_instr) + elif opcode == opcodedesc.LOAD_CLOSURE.index: + self.LOAD_CLOSURE(oparg, next_instr) + elif opcode == opcodedesc.LOAD_CONST.index: + self.LOAD_CONST(oparg, next_instr) + elif opcode == opcodedesc.LOAD_DEREF.index: + self.LOAD_DEREF(oparg, next_instr) + elif opcode == opcodedesc.LOAD_FAST.index: + self.LOAD_FAST(oparg, next_instr) + elif opcode == opcodedesc.LOAD_GLOBAL.index: + self.LOAD_GLOBAL(oparg, next_instr) + elif opcode == opcodedesc.LOAD_LOCALS.index: + self.LOAD_LOCALS(oparg, next_instr) + elif opcode == opcodedesc.LOAD_NAME.index: + self.LOAD_NAME(oparg, next_instr) + elif opcode == opcodedesc.LOOKUP_METHOD.index: + self.LOOKUP_METHOD(oparg, next_instr) + elif opcode == opcodedesc.MAKE_CLOSURE.index: + self.MAKE_CLOSURE(oparg, next_instr) + elif opcode == opcodedesc.MAKE_FUNCTION.index: + self.MAKE_FUNCTION(oparg, next_instr) + elif opcode == opcodedesc.MAP_ADD.index: + self.MAP_ADD(oparg, next_instr) + elif opcode == opcodedesc.NOP.index: + self.NOP(oparg, next_instr) + elif opcode == opcodedesc.POP_BLOCK.index: + self.POP_BLOCK(oparg, next_instr) + elif opcode == opcodedesc.POP_TOP.index: + self.POP_TOP(oparg, next_instr) + elif opcode == opcodedesc.PRINT_EXPR.index: + self.PRINT_EXPR(oparg, next_instr) + elif opcode == opcodedesc.PRINT_ITEM.index: + self.PRINT_ITEM(oparg, next_instr) + elif opcode == opcodedesc.PRINT_ITEM_TO.index: + self.PRINT_ITEM_TO(oparg, next_instr) + elif opcode == opcodedesc.PRINT_NEWLINE.index: + self.PRINT_NEWLINE(oparg, next_instr) + elif opcode == opcodedesc.PRINT_NEWLINE_TO.index: + self.PRINT_NEWLINE_TO(oparg, next_instr) + elif opcode == opcodedesc.RAISE_VARARGS.index: + self.RAISE_VARARGS(oparg, next_instr) + elif opcode == opcodedesc.ROT_FOUR.index: + self.ROT_FOUR(oparg, next_instr) + elif opcode == opcodedesc.ROT_THREE.index: + self.ROT_THREE(oparg, next_instr) + elif opcode == opcodedesc.ROT_TWO.index: + self.ROT_TWO(oparg, next_instr) + elif opcode == opcodedesc.SETUP_EXCEPT.index: + self.SETUP_EXCEPT(oparg, next_instr) + elif opcode == opcodedesc.SETUP_FINALLY.index: + self.SETUP_FINALLY(oparg, next_instr) + elif opcode == opcodedesc.SETUP_LOOP.index: + self.SETUP_LOOP(oparg, next_instr) + elif opcode == opcodedesc.SETUP_WITH.index: + self.SETUP_WITH(oparg, next_instr) + elif opcode == opcodedesc.SET_ADD.index: + self.SET_ADD(oparg, next_instr) + elif opcode == opcodedesc.SLICE_0.index: + self.SLICE_0(oparg, next_instr) + elif opcode == opcodedesc.SLICE_1.index: + self.SLICE_1(oparg, next_instr) + elif opcode == opcodedesc.SLICE_2.index: + self.SLICE_2(oparg, next_instr) + elif opcode == opcodedesc.SLICE_3.index: + self.SLICE_3(oparg, next_instr) + elif opcode == opcodedesc.STOP_CODE.index: + self.STOP_CODE(oparg, next_instr) + elif opcode == opcodedesc.STORE_ATTR.index: + self.STORE_ATTR(oparg, next_instr) + elif opcode == opcodedesc.STORE_DEREF.index: + self.STORE_DEREF(oparg, next_instr) + elif opcode == opcodedesc.STORE_FAST.index: + self.STORE_FAST(oparg, next_instr) + elif opcode == opcodedesc.STORE_GLOBAL.index: + self.STORE_GLOBAL(oparg, next_instr) + elif opcode == opcodedesc.STORE_MAP.index: + self.STORE_MAP(oparg, next_instr) + elif opcode == opcodedesc.STORE_NAME.index: + self.STORE_NAME(oparg, next_instr) + elif opcode == opcodedesc.STORE_SLICE_0.index: + self.STORE_SLICE_0(oparg, next_instr) + elif opcode == opcodedesc.STORE_SLICE_1.index: + self.STORE_SLICE_1(oparg, next_instr) + elif opcode == opcodedesc.STORE_SLICE_2.index: + self.STORE_SLICE_2(oparg, next_instr) + elif opcode == opcodedesc.STORE_SLICE_3.index: + self.STORE_SLICE_3(oparg, next_instr) + elif opcode == opcodedesc.STORE_SUBSCR.index: + self.STORE_SUBSCR(oparg, next_instr) + elif opcode == opcodedesc.UNARY_CONVERT.index: + self.UNARY_CONVERT(oparg, next_instr) + elif opcode == opcodedesc.UNARY_INVERT.index: + self.UNARY_INVERT(oparg, next_instr) + elif opcode == opcodedesc.UNARY_NEGATIVE.index: + self.UNARY_NEGATIVE(oparg, next_instr) + elif opcode == opcodedesc.UNARY_NOT.index: + self.UNARY_NOT(oparg, next_instr) + elif opcode == opcodedesc.UNARY_POSITIVE.index: + self.UNARY_POSITIVE(oparg, next_instr) + elif opcode == opcodedesc.UNPACK_SEQUENCE.index: + self.UNPACK_SEQUENCE(oparg, next_instr) + elif opcode == opcodedesc.WITH_CLEANUP.index: + self.WITH_CLEANUP(oparg, next_instr) + elif opcode == opcodedesc.YIELD_VALUE.index: + self.YIELD_VALUE(oparg, next_instr) + else: + self.MISSING_OPCODE(oparg, next_instr) if jit.we_are_jitted(): return next_instr @@ -733,36 +908,6 @@ self.pushvalue(w_value) LOAD_ATTR._always_inline_ = True - def cmp_lt(self, w_1, w_2): - return self.space.lt(w_1, w_2) - - def cmp_le(self, w_1, w_2): - return self.space.le(w_1, w_2) - - def cmp_eq(self, w_1, w_2): - return self.space.eq(w_1, w_2) - - def cmp_ne(self, w_1, w_2): - return self.space.ne(w_1, w_2) - - def cmp_gt(self, w_1, w_2): - return self.space.gt(w_1, w_2) - - def cmp_ge(self, w_1, w_2): - return self.space.ge(w_1, w_2) - - def cmp_in(self, w_1, w_2): - return self.space.contains(w_2, w_1) - - def cmp_not_in(self, w_1, w_2): - return self.space.not_(self.space.contains(w_2, w_1)) - - def cmp_is(self, w_1, w_2): - return self.space.is_(w_1, w_2) - - def cmp_is_not(self, w_1, w_2): - return self.space.not_(self.space.is_(w_1, w_2)) - @jit.unroll_safe def cmp_exc_match(self, w_1, w_2): space = self.space @@ -779,11 +924,28 @@ def COMPARE_OP(self, testnum, next_instr): w_2 = self.popvalue() w_1 = self.popvalue() - w_result = None - for i, attr in unrolling_compare_dispatch_table: - if i == testnum: - w_result = getattr(self, attr)(w_1, w_2) - break + if testnum == 0: + w_result = self.space.lt(w_1, w_2) + elif testnum == 1: + w_result = self.space.le(w_1, w_2) + elif testnum == 2: + w_result = self.space.eq(w_1, w_2) + elif testnum == 3: + w_result = self.space.ne(w_1, w_2) + elif testnum == 4: + w_result = self.space.gt(w_1, w_2) + elif testnum == 5: + w_result = self.space.ge(w_1, w_2) + elif testnum == 6: + w_result = self.space.contains(w_2, w_1) + elif testnum == 7: + w_result = self.space.not_(self.space.contains(w_2, w_1)) + elif testnum == 8: + w_result = self.space.is_(w_1, w_2) + elif testnum == 9: + w_result = self.space.not_(self.space.is_(w_1, w_2)) + elif testnum == 10: + w_result = self.cmp_exc_match(w_1, w_2) else: raise BytecodeCorruption("bad COMPARE_OP oparg") self.pushvalue(w_result) @@ -1086,49 +1248,6 @@ self.space.setitem(w_dict, w_key, w_value) -class __extend__(pyframe.CPythonFrame): - - def JUMP_IF_FALSE(self, stepby, next_instr): - w_cond = self.peekvalue() - if not self.space.is_true(w_cond): - next_instr += stepby - return next_instr - - def JUMP_IF_TRUE(self, stepby, next_instr): - w_cond = self.peekvalue() - if self.space.is_true(w_cond): - next_instr += stepby - return next_instr - - def BUILD_MAP(self, itemcount, next_instr): - if sys.version_info >= (2, 6): - # We could pre-allocate a dict here - # but for the moment this code is not translated. - pass - else: - if itemcount != 0: - raise BytecodeCorruption - w_dict = self.space.newdict() - self.pushvalue(w_dict) - - def STORE_MAP(self, zero, next_instr): - if sys.version_info >= (2, 6): - w_key = self.popvalue() - w_value = self.popvalue() - w_dict = self.peekvalue() - self.space.setitem(w_dict, w_key, w_value) - else: - raise BytecodeCorruption - - def LIST_APPEND(self, oparg, next_instr): - w = self.popvalue() - if sys.version_info < (2, 7): - v = self.popvalue() - else: - v = self.peekvalue(oparg - 1) - self.space.call_method(v, 'append', w) - - ### ____________________________________________________________ ### class ExitFrame(Exception): 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 @@ -953,10 +953,6 @@ assert i > -1 assert isinstance(co.co_consts[i], frozenset) - -class AppTestCallMethod(object): - spaceconfig = {'objspace.opcodes.CALL_METHOD': True} - def test_call_method_kwargs(self): source = """def _f(a): return a.f(a=a) diff --git a/pypy/interpreter/test/test_executioncontext.py b/pypy/interpreter/test/test_executioncontext.py --- a/pypy/interpreter/test/test_executioncontext.py +++ b/pypy/interpreter/test/test_executioncontext.py @@ -253,10 +253,6 @@ """) -class TestExecutionContextWithCallMethod(TestExecutionContext): - spaceconfig ={'objspace.opcodes.CALL_METHOD': True} - - class AppTestDelNotBlocked: def setup_method(self, meth): 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 @@ -812,10 +812,6 @@ assert len(called) == 1 assert isinstance(called[0], argument.Arguments) -class TestPassThroughArguments_CALL_METHOD(TestPassThroughArguments): - spaceconfig = dict(usemodules=('itertools',), **{ - "objspace.opcodes.CALL_METHOD": True - }) class AppTestKeywordsToBuiltinSanity(object): 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 @@ -1516,13 +1516,18 @@ d = BStruct.fields assert d[0][1].offset == d[1][1].offset == d[2][1].offset == 0 assert d[3][1].offset == sizeof(BLong) - assert d[0][1].bitshift == 0 + def f(m, r): + if sys.byteorder == 'little': + return r + else: + return LONGBITS - m - r + assert d[0][1].bitshift == f(1, 0) assert d[0][1].bitsize == 1 - assert d[1][1].bitshift == 1 + assert d[1][1].bitshift == f(2, 1) assert d[1][1].bitsize == 2 - assert d[2][1].bitshift == 3 + assert d[2][1].bitshift == f(3, 3) assert d[2][1].bitsize == 3 - assert d[3][1].bitshift == 0 + assert d[3][1].bitshift == f(LONGBITS - 5, 0) assert d[3][1].bitsize == LONGBITS - 5 assert sizeof(BStruct) == 2 * sizeof(BLong) assert alignof(BStruct) == alignof(BLong) @@ -2856,7 +2861,7 @@ ('b1', BInt, 9), ('b2', BUInt, 7), ('c', BChar, -1)], -1, -1, -1, flag) - if flag % 2 == 0: # gcc and gcc ARM + if flag % 2 == 0: # gcc, any variant assert typeoffsetof(BStruct, 'c') == (BChar, 3) assert sizeof(BStruct) == 4 else: # msvc @@ -2864,6 +2869,31 @@ assert sizeof(BStruct) == 12 assert alignof(BStruct) == 4 # + p = newp(new_pointer_type(BStruct), None) + p.a = b'A' + p.b1 = -201 + p.b2 = 99 + p.c = b'\x9D' + raw = buffer(p)[:] + if sys.byteorder == 'little': + if flag == 0 or flag == 2: # gcc, little endian + assert raw == b'A7\xC7\x9D' + elif flag == 1: # msvc + assert raw == b'A\x00\x00\x007\xC7\x00\x00\x9D\x00\x00\x00' + elif flag == 4: # gcc, big endian + assert raw == b'A\xE3\x9B\x9D' + else: + raise AssertionError("bad flag") + else: + if flag == 0 or flag == 2: # gcc + assert raw == b'A\xC77\x9D' + elif flag == 1: # msvc + assert raw == b'A\x00\x00\x00\x00\x00\xC77\x9D\x00\x00\x00' + elif flag == 4: # gcc, big endian + assert raw == b'A\x9B\xE3\x9D' + else: + raise AssertionError("bad flag") + # BStruct = new_struct_type("struct foo2") complete_struct_or_union(BStruct, [('a', BChar, -1), ('', BShort, 9), @@ -2875,16 +2905,21 @@ elif flag == 1: # msvc assert sizeof(BStruct) == 6 assert alignof(BStruct) == 2 - else: # gcc ARM + elif flag == 2: # gcc ARM assert sizeof(BStruct) == 6 assert alignof(BStruct) == 2 + elif flag == 4: # gcc, big endian + assert sizeof(BStruct) == 5 + assert alignof(BStruct) == 1 + else: + raise AssertionError("bad flag") # BStruct = new_struct_type("struct foo2") complete_struct_or_union(BStruct, [('a', BChar, -1), ('', BInt, 0), ('', BInt, 0), ('c', BChar, -1)], -1, -1, -1, flag) - if flag == 0: # gcc + if flag == 0: # gcc assert typeoffsetof(BStruct, 'c') == (BChar, 4) assert sizeof(BStruct) == 5 assert alignof(BStruct) == 1 @@ -2892,10 +2927,16 @@ assert typeoffsetof(BStruct, 'c') == (BChar, 1) assert sizeof(BStruct) == 2 assert alignof(BStruct) == 1 - else: # gcc ARM + elif flag == 2: # gcc ARM assert typeoffsetof(BStruct, 'c') == (BChar, 4) assert sizeof(BStruct) == 8 assert alignof(BStruct) == 4 + elif flag == 4: # gcc, big endian + assert typeoffsetof(BStruct, 'c') == (BChar, 4) + assert sizeof(BStruct) == 5 + assert alignof(BStruct) == 1 + else: + raise AssertionError("bad flag") def test_bitfield_as_gcc(): @@ -2907,6 +2948,11 @@ def test_bitfield_as_arm_gcc(): _test_bitfield_details(flag=2) +def test_bitfield_as_big_endian(): + if '__pypy__' in sys.builtin_module_names: + py.test.skip("no big endian machine supported on pypy for now") + _test_bitfield_details(flag=4) + def test_version(): # this test is here mostly for PyPy diff --git a/pypy/module/_continuation/interp_pickle.py b/pypy/module/_continuation/interp_pickle.py --- a/pypy/module/_continuation/interp_pickle.py +++ b/pypy/module/_continuation/interp_pickle.py @@ -120,8 +120,7 @@ nkwds = (oparg >> 8) & 0xff if nkwds == 0: # only positional arguments # fast paths leaves things on the stack, pop them - if (frame.space.config.objspace.opcodes.CALL_METHOD and - opcode == map['CALL_METHOD']): + if opcode == map['CALL_METHOD']: frame.dropvalues(nargs + 2) elif opcode == map['CALL_FUNCTION']: frame.dropvalues(nargs + 1) diff --git a/pypy/module/_continuation/test/test_zpickle.py b/pypy/module/_continuation/test/test_zpickle.py --- a/pypy/module/_continuation/test/test_zpickle.py +++ b/pypy/module/_continuation/test/test_zpickle.py @@ -1,8 +1,7 @@ class AppTestCopy: spaceconfig = dict(usemodules=['_continuation'], - continuation=True, - CALL_METHOD=True) + continuation=True) def test_basic_setup(self): from _continuation import continulet @@ -104,7 +103,6 @@ spaceconfig = { "usemodules": ['_continuation', 'struct', 'binascii'], "continuation": True, - "CALL_METHOD": True, } def setup_class(cls): diff --git a/pypy/module/_lsprof/test/test_cprofile.py b/pypy/module/_lsprof/test/test_cprofile.py --- a/pypy/module/_lsprof/test/test_cprofile.py +++ b/pypy/module/_lsprof/test/test_cprofile.py @@ -191,11 +191,6 @@ sys.path.pop(0) -class AppTestWithDifferentBytecodes(AppTestCProfile): - spaceconfig = AppTestCProfile.spaceconfig.copy() - spaceconfig['objspace.opcodes.CALL_METHOD'] = True - - expected_output = {} expected_output['print_stats'] = """\ 126 function calls (106 primitive calls) in 1.000 seconds 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 @@ -841,8 +841,7 @@ # # default_magic - 6 -- used by CPython without the -U option # default_magic - 5 -- used by CPython with the -U option -# default_magic -- used by PyPy without the CALL_METHOD opcode -# default_magic + 2 -- used by PyPy with the CALL_METHOD opcode +# default_magic -- used by PyPy [because of CALL_METHOD] # from pypy.interpreter.pycode import default_magic MARSHAL_VERSION_FOR_PYC = 2 @@ -855,10 +854,7 @@ magic = __import__('imp').get_magic() return struct.unpack('" - "ge", # ">=" - ] -unrolling_compare_ops = unrolling_iterable(enumerate(compare_table)) - -def fast_COMPARE_OP(f, testnum, next_instr): - w_2 = f.popvalue() - w_1 = f.popvalue() - w_result = None - if (type(w_2) is intobject.W_IntObject and - type(w_1) is intobject.W_IntObject and - testnum < len(compare_table)): - for i, attr in unrolling_compare_ops: - if i == testnum: - op = getattr(operator, attr) - w_result = f.space.newbool(op(w_1.intval, - w_2.intval)) - break - else: - for i, attr in pyopcode.unrolling_compare_dispatch_table: - if i == testnum: - w_result = getattr(f, attr)(w_1, w_2) - break - else: - raise pyopcode.BytecodeCorruption, "bad COMPARE_OP oparg" - f.pushvalue(w_result) - def build_frame(space): """Consider the objspace config and return a patched frame object.""" @@ -91,10 +59,7 @@ 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: - from pypy.objspace.std.callmethod import LOOKUP_METHOD, CALL_METHOD - StdObjSpaceFrame.LOOKUP_METHOD = LOOKUP_METHOD - StdObjSpaceFrame.CALL_METHOD = CALL_METHOD - if space.config.objspace.std.optimized_comparison_op: - StdObjSpaceFrame.COMPARE_OP = fast_COMPARE_OP + from pypy.objspace.std.callmethod import LOOKUP_METHOD, CALL_METHOD + StdObjSpaceFrame.LOOKUP_METHOD = LOOKUP_METHOD + StdObjSpaceFrame.CALL_METHOD = CALL_METHOD return StdObjSpaceFrame 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 @@ -39,9 +39,6 @@ def _never_equal_to(self, w_lookup_type): return False - def w_keys(self, w_dict): - 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): if self.is_correct_type(w_key): self.setitem_str(w_dict, self.unwrap(w_key), w_value) @@ -57,7 +54,6 @@ jit.isconstant(self.length(w_dict)) and jit.isconstant(key)) def _setitem_str_indirection(self, w_dict, key, w_value): keys, values_w = self.unerase(w_dict.dstorage) - result = [] for i in range(len(keys)): if keys[i] == key: values_w[i] = w_value @@ -72,7 +68,6 @@ values_w.append(w_value) def setdefault(self, w_dict, 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) @@ -99,7 +94,6 @@ 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 = [] for i in range(len(keys)): if keys[i] == key: return values_w[i] @@ -164,14 +158,18 @@ def getiterkeys(self, w_dict): return iter(self.unerase(w_dict.dstorage)[0]) + def getitervalues(self, w_dict): return iter(self.unerase(w_dict.dstorage)[1]) + def getiteritems(self, w_dict): keys = self.unerase(w_dict.dstorage)[0] return iter(range(len(keys))) + def wrapkey(space, key): return space.wrap(key) + def next_item(self): strategy = self.strategy assert isinstance(strategy, KwargsDictStrategy) 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 @@ -562,8 +562,6 @@ 'L.reverse() -- reverse *IN PLACE*' self.reverse() - @jit.look_inside_iff(lambda self, space, w_value: - jit.loop_unrolling_heuristic(self, self.length(), UNROLL_CUTOFF)) def descr_count(self, space, w_value): '''L.count(value) -> integer -- return number of occurrences of value''' 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 @@ -591,10 +591,7 @@ return ObjSpace.getindex_w(self, w_obj, w_exception, objdescr) def call_method(self, w_obj, methname, *arg_w): - if self.config.objspace.opcodes.CALL_METHOD: - return callmethod.call_method_opt(self, w_obj, methname, *arg_w) - else: - return ObjSpace.call_method(self, w_obj, methname, *arg_w) + return callmethod.call_method_opt(self, w_obj, methname, *arg_w) def _type_issubtype(self, w_sub, w_type): if isinstance(w_sub, W_TypeObject) and isinstance(w_type, W_TypeObject): 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 @@ -233,13 +233,13 @@ return space.wrap(builder.build()) -def str_title__String(space, w_self): - input = w_self._value - builder = StringBuilder(len(input)) + + at jit.elidable +def title(s): + builder = StringBuilder(len(s)) prev_letter = ' ' - for pos in range(len(input)): - ch = input[pos] + for ch in s: if not prev_letter.isalpha(): ch = _upper(ch) builder.append(ch) @@ -248,39 +248,17 @@ builder.append(ch) prev_letter = ch + return builder.build() - return space.wrap(builder.build()) + +def str_title__String(space, w_self): + return space.wrap(title(w_self._value)) + def str_split__String_None_ANY(space, w_self, w_none, w_maxsplit=-1): maxsplit = space.int_w(w_maxsplit) - res = [] value = w_self._value - length = len(value) - i = 0 - while True: - # find the beginning of the next word - while i < length: - if not value[i].isspace(): - break # found - i += 1 - else: - break # end of string, finished - - # find the end of the word - if maxsplit == 0: - j = length # take all the rest of the string - else: - j = i + 1 - while j < length and not value[j].isspace(): - j += 1 - maxsplit -= 1 # NB. if it's already < 0, it stays < 0 - - # the word is value[i:j] - res.append(value[i:j]) - - # continue to look from the character following the space after the word - i = j + 1 - + res = split(value, maxsplit=maxsplit) return space.newlist_str(res) def str_split__String_String_ANY(space, w_self, w_by, w_maxsplit=-1): @@ -295,37 +273,8 @@ def str_rsplit__String_None_ANY(space, w_self, w_none, w_maxsplit=-1): maxsplit = space.int_w(w_maxsplit) - res = [] value = w_self._value - i = len(value)-1 - while True: - # starting from the end, find the end of the next word - while i >= 0: - if not value[i].isspace(): - break # found - i -= 1 - else: - break # end of string, finished - - # find the start of the word - # (more precisely, 'j' will be the space character before the word) - if maxsplit == 0: - j = -1 # take all the rest of the string - else: - j = i - 1 - while j >= 0 and not value[j].isspace(): - j -= 1 - maxsplit -= 1 # NB. if it's already < 0, it stays < 0 - - # the word is value[j+1:i+1] - j1 = j + 1 - assert j1 >= 0 - res.append(value[j1:i+1]) - - # continue to look from the character before the space before the word - i = j - 1 - - res.reverse() + res = rsplit(value, maxsplit=maxsplit) return space.newlist_str(res) def str_rsplit__String_String_ANY(space, w_self, w_by, w_maxsplit=-1): diff --git a/pypy/objspace/std/test/test_callmethod.py b/pypy/objspace/std/test/test_callmethod.py --- a/pypy/objspace/std/test/test_callmethod.py +++ b/pypy/objspace/std/test/test_callmethod.py @@ -2,8 +2,6 @@ # The exec hacking is needed to have the code snippets compiled # by our own compiler, not CPython's - spaceconfig = {"objspace.opcodes.CALL_METHOD": True} - def test_call_method(self): exec """if 1: class C(object): @@ -111,13 +109,10 @@ class AppTestCallMethodWithGetattributeShortcut(AppTestCallMethod): - spaceconfig = AppTestCallMethod.spaceconfig.copy() - spaceconfig["objspace.std.getattributeshortcut"] = True + spaceconfig = {"objspace.std.getattributeshortcut": True} class TestCallMethod: - spaceconfig = {"objspace.opcodes.CALL_METHOD": True} - def test_space_call_method(self): space = self.space w_lst = space.newlist([]) 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 @@ -501,6 +501,3 @@ class AppTestIntOptimizedAdd(AppTestInt): spaceconfig = {"objspace.std.optimized_int_add": True} - -class AppTestIntOptimizedComp(AppTestInt): - spaceconfig = {"objspace.std.optimized_comparison_op": True} diff --git a/pypy/objspace/std/test/test_mapdict.py b/pypy/objspace/std/test/test_mapdict.py --- a/pypy/objspace/std/test/test_mapdict.py +++ b/pypy/objspace/std/test/test_mapdict.py @@ -656,8 +656,7 @@ class AppTestWithMapDictAndCounters(object): spaceconfig = {"objspace.std.withmapdict": True, - "objspace.std.withmethodcachecounter": True, - "objspace.opcodes.CALL_METHOD": True} + "objspace.std.withmethodcachecounter": True} def setup_class(cls): from pypy.interpreter import gateway @@ -1001,8 +1000,7 @@ class AppTestGlobalCaching(AppTestWithMapDict): spaceconfig = {"objspace.std.withmethodcachecounter": True, - "objspace.std.withmapdict": True, - "objspace.opcodes.CALL_METHOD": True} + "objspace.std.withmapdict": True} def test_mix_classes(self): import __pypy__ diff --git a/pypy/tool/pytest/apptest.py b/pypy/tool/pytest/apptest.py --- a/pypy/tool/pytest/apptest.py +++ b/pypy/tool/pytest/apptest.py @@ -34,6 +34,8 @@ try: target(*args) except OperationError, e: + if self.config.option.verbose: + raise tb = sys.exc_info()[2] if e.match(space, space.w_KeyboardInterrupt): raise KeyboardInterrupt, KeyboardInterrupt(), tb diff --git a/rpython/annotator/argument.py b/rpython/annotator/argument.py --- a/rpython/annotator/argument.py +++ b/rpython/annotator/argument.py @@ -25,7 +25,7 @@ return [Ellipsis] raise CallPatternTooComplex("'*' argument must be SomeTuple") - def is_true(self, s_tup): + def bool(self, s_tup): assert isinstance(s_tup, SomeTuple) return bool(s_tup.items) @@ -208,7 +208,7 @@ args_w = data_args_w[:need_cnt] for argname, w_arg in zip(argnames[need_cnt:], data_args_w[need_cnt:]): unfiltered_kwds_w[argname] = w_arg - assert not space.is_true(data_w_stararg) + assert not space.bool(data_w_stararg) else: stararg_w = space.unpackiterable(data_w_stararg) args_w = data_args_w + stararg_w diff --git a/rpython/annotator/binaryop.py b/rpython/annotator/binaryop.py --- a/rpython/annotator/binaryop.py +++ b/rpython/annotator/binaryop.py @@ -825,14 +825,14 @@ if pbc.isNone(): return %(classname)s(%(constructor_args)s) else: - return SomeObject() + raise UnionError(pbc, obj) class __extend__(pairtype(SomePBC, %(classname)s)): def union((pbc, obj)): if pbc.isNone(): return %(classname)s(%(constructor_args)s) else: - return SomeObject() + raise UnionError(pbc, obj) """ % loc) exec source.compile() in glob diff --git a/rpython/annotator/bookkeeper.py b/rpython/annotator/bookkeeper.py --- a/rpython/annotator/bookkeeper.py +++ b/rpython/annotator/bookkeeper.py @@ -688,7 +688,7 @@ fn, block, i = self.position_key op = block.operations[i] if opname is not None: - assert op.opname == opname or op.opname in opname + assert op.opname == opname if arity is not None: assert len(op.args) == arity if pos is not None: diff --git a/rpython/annotator/builtin.py b/rpython/annotator/builtin.py --- a/rpython/annotator/builtin.py +++ b/rpython/annotator/builtin.py @@ -94,7 +94,7 @@ def builtin_bool(s_obj): - return s_obj.is_true() + return s_obj.bool() def builtin_int(s_obj, s_base=None): if isinstance(s_obj, SomeInteger): diff --git a/rpython/annotator/listdef.py b/rpython/annotator/listdef.py --- a/rpython/annotator/listdef.py +++ b/rpython/annotator/listdef.py @@ -1,12 +1,12 @@ from rpython.annotator.model import s_ImpossibleValue from rpython.annotator.model import SomeList, SomeString -from rpython.annotator.model import unionof, TLS, UnionError +from rpython.annotator.model import unionof, TLS, UnionError, AnnotatorError -class TooLateForChange(Exception): +class TooLateForChange(AnnotatorError): pass -class ListChangeUnallowed(Exception): +class ListChangeUnallowed(AnnotatorError): pass class ListItem(object): diff --git a/rpython/annotator/signature.py b/rpython/annotator/signature.py --- a/rpython/annotator/signature.py +++ b/rpython/annotator/signature.py @@ -5,7 +5,7 @@ from rpython.annotator.model import SomeBool, SomeInteger, SomeString,\ SomeFloat, SomeList, SomeDict, s_None, \ SomeObject, SomeInstance, SomeTuple, lltype_to_annotation,\ - unionof, SomeUnicodeString, SomeType + unionof, SomeUnicodeString, SomeType, AnnotatorError from rpython.annotator.listdef import ListDef from rpython.annotator.dictdef import DictDef @@ -118,25 +118,28 @@ else: args_s.append(annotation(argtype, bookkeeper=funcdesc.bookkeeper)) if len(inputcells) != len(args_s): - raise Exception("%r: expected %d args, got %d" % (funcdesc, + raise SignatureError("%r: expected %d args, got %d" % (funcdesc, len(args_s), len(inputcells))) for i, (s_arg, s_input) in enumerate(zip(args_s, inputcells)): s_input = unionof(s_input, s_arg) if not s_arg.contains(s_input): - raise Exception("%r argument %d:\n" + raise SignatureError("%r argument %d:\n" "expected %s,\n" " got %s" % (funcdesc, i+1, s_arg, s_input)) inputcells[:] = args_s +class SignatureError(AnnotatorError): + pass + def finish_type(paramtype, bookkeeper, func): 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,)) + raise SignatureError("%r argument declared as annotation.types.self(); class needs decorator rlib.signature.finishsigs()" % (func,)) elif isinstance(paramtype, AnyTypeMarker): return None else: @@ -149,7 +152,7 @@ if s_param is None: # can be anything continue if not s_param.contains(s_actual): - raise Exception("%r argument %d:\n" + raise SignatureError("%r argument %d:\n" "expected %s,\n" " got %s" % (funcdesc, i+1, s_param, s_actual)) for i, s_param in enumerate(params_s): @@ -160,7 +163,7 @@ def enforce_signature_return(funcdesc, sigtype, inferredtype): s_sigret = finish_type(sigtype, funcdesc.bookkeeper, funcdesc.pyobj) if s_sigret is not None and not s_sigret.contains(inferredtype): - raise Exception("%r return value:\n" + raise SignatureError("%r return value:\n" "expected %s,\n" " got %s" % (funcdesc, s_sigret, inferredtype)) return s_sigret diff --git a/rpython/annotator/specialize.py b/rpython/annotator/specialize.py --- a/rpython/annotator/specialize.py +++ b/rpython/annotator/specialize.py @@ -258,16 +258,17 @@ assert not s.can_be_None, "memo call: cannot mix None and PBCs" for desc in s.descriptions: if desc.pyobj is None: - raise Exception("memo call with a class or PBC that has no " - "corresponding Python object (%r)" % (desc,)) + raise annmodel.AnnotatorError( + "memo call with a class or PBC that has no " + "corresponding Python object (%r)" % (desc,)) values.append(desc.pyobj) elif isinstance(s, SomeImpossibleValue): return s # we will probably get more possible args later elif isinstance(s, SomeBool): values = [False, True] else: - raise Exception("memo call: argument must be a class or a frozen " - "PBC, got %r" % (s,)) + raise annmodel.AnnotatorError("memo call: argument must be a class" + "or a frozen PBC, got %r" % (s,)) argvalues.append(values) # the list of all possible tuples of arguments to give to the memo function possiblevalues = cartesian_product(argvalues) @@ -280,8 +281,8 @@ except KeyError: func = funcdesc.pyobj if func is None: - raise Exception("memo call: no Python function object to call " - "(%r)" % (funcdesc,)) + raise annmodel.AnnotatorError("memo call: no Python function object" + "to call (%r)" % (funcdesc,)) def compute_one_result(args): value = func(*args) @@ -344,8 +345,8 @@ desc, = s.descriptions key.append(desc) else: - raise Exception("specialize:arg(%d): argument not constant: %r" - % (i, s)) + raise annmodel.AnnotatorError("specialize:arg(%d): argument not " + "constant: %r" % (i, s)) key = tuple(key) return maybe_star_args(funcdesc, key, 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 @@ -1490,7 +1490,7 @@ s = a.build_types(snippet.prime, [int]) assert s.knowntype == bool - def test_and_is_true_coalesce(self): + def test_and_bool_coalesce(self): def f(a,b,c,d,e): x = a and b if x: @@ -1500,7 +1500,7 @@ s = a.build_types(f, [int, str, a.bookkeeper.immutablevalue(1.0), a.bookkeeper.immutablevalue('d'), a.bookkeeper.immutablevalue('e')]) assert s == annmodel.SomeTuple([annmodel.SomeChar(), a.bookkeeper.immutablevalue(1.0)]) - def test_is_true_coalesce2(self): + def test_bool_coalesce2(self): def f(a,b,a1,b1,c,d,e): x = (a or b) and (a1 or b1) if x: @@ -1514,7 +1514,7 @@ assert s == annmodel.SomeTuple([annmodel.SomeChar(), a.bookkeeper.immutablevalue(1.0)]) - def test_is_true_coalesce_sanity(self): + def test_bool_coalesce_sanity(self): def f(a): while a: pass diff --git a/rpython/annotator/test/test_argument.py b/rpython/annotator/test/test_argument.py --- a/rpython/annotator/test/test_argument.py +++ b/rpython/annotator/test/test_argument.py @@ -7,7 +7,7 @@ def newtuple(self, items): return tuple(items) - def is_true(self, obj): + def bool(self, obj): return bool(obj) def unpackiterable(self, it): diff --git a/rpython/annotator/unaryop.py b/rpython/annotator/unaryop.py --- a/rpython/annotator/unaryop.py +++ b/rpython/annotator/unaryop.py @@ -20,10 +20,10 @@ def immutablevalue(x): return getbookkeeper().immutablevalue(x) -UNARY_OPERATIONS = set(['len', 'is_true', 'getattr', 'setattr', 'delattr', +UNARY_OPERATIONS = set(['len', 'bool', 'getattr', 'setattr', 'delattr', 'simple_call', 'call_args', 'str', 'repr', 'iter', 'next', 'invert', 'type', 'issubtype', - 'pos', 'neg', 'nonzero', 'abs', 'hex', 'oct', + 'pos', 'neg', 'abs', 'hex', 'oct', 'ord', 'int', 'float', 'long', 'hash', 'id', # <== not supported any more 'getslice', 'setslice', 'delslice', @@ -57,7 +57,7 @@ def len(obj): return SomeInteger(nonneg=True) - def is_true_behavior(obj, s): + def bool_behavior(obj, s): if obj.is_immutable_constant(): s.const = bool(obj.const) else: @@ -65,13 +65,13 @@ if s_len.is_immutable_constant(): s.const = s_len.const > 0 - def is_true(s_obj): + def bool(s_obj): r = SomeBool() - s_obj.is_true_behavior(r) + s_obj.bool_behavior(r) bk = getbookkeeper() knowntypedata = {} - op = bk._find_current_op(opname=("is_true", "nonzero"), arity=1) + op = bk._find_current_op(opname="bool", arity=1) arg = op.args[0] s_nonnone_obj = s_obj if s_obj.can_be_none(): @@ -80,9 +80,6 @@ r.set_knowntypedata(knowntypedata) return r - def nonzero(obj): - return obj.is_true() - def hash(obj): raise AnnotatorError("cannot use hash() in RPython") @@ -176,7 +173,7 @@ abs = neg - def is_true(self): + def bool(self): if self.is_immutable_constant(): return getbookkeeper().immutablevalue(bool(self.const)) return s_Bool @@ -208,7 +205,7 @@ abs_ovf = _clone(abs, [OverflowError]) class __extend__(SomeBool): - def is_true(self): + def bool(self): return self def invert(self): @@ -667,7 +664,7 @@ # create or update the attribute in clsdef clsdef.generalize_attr(attr, s_value) - def is_true_behavior(ins, s): + def bool_behavior(ins, s): if not ins.can_be_None: s.const = True @@ -736,7 +733,7 @@ d = [desc.bind_under(classdef, name) for desc in pbc.descriptions] return SomePBC(d, can_be_None=pbc.can_be_None) - def is_true_behavior(pbc, s): + def bool_behavior(pbc, s): if pbc.isNone(): s.const = False elif not pbc.can_be_None: @@ -797,7 +794,7 @@ v = p.ll_ptrtype._example()(*llargs) return ll_to_annotation(v) - def is_true(p): + def bool(p): return s_Bool class __extend__(SomeLLADTMeth): @@ -831,5 +828,5 @@ llmemory.supported_access_types[s_attr.const]) getattr.can_only_throw = [] - def is_true(s_addr): + def bool(s_addr): return s_Bool diff --git a/rpython/flowspace/bytecode.py b/rpython/flowspace/bytecode.py --- a/rpython/flowspace/bytecode.py +++ b/rpython/flowspace/bytecode.py @@ -3,6 +3,7 @@ """ from rpython.tool.stdlib_opcode import host_bytecode_spec from opcode import EXTENDED_ARG, HAVE_ARGUMENT +import opcode from rpython.flowspace.argument import Signature from rpython.flowspace.flowcontext import BytecodeCorruption @@ -83,10 +84,10 @@ Returns (next_instr, opname, oparg). """ co_code = self.co_code - opcode = ord(co_code[pos]) + opnum = ord(co_code[pos]) next_instr = pos + 1 - if opcode >= HAVE_ARGUMENT: + if opnum >= HAVE_ARGUMENT: lo = ord(co_code[next_instr]) hi = ord(co_code[next_instr+1]) next_instr += 2 @@ -94,16 +95,18 @@ else: oparg = 0 - while opcode == EXTENDED_ARG: - opcode = ord(co_code[next_instr]) - if opcode < HAVE_ARGUMENT: + while opnum == EXTENDED_ARG: + opnum = ord(co_code[next_instr]) + if opnum < HAVE_ARGUMENT: raise BytecodeCorruption lo = ord(co_code[next_instr+1]) hi = ord(co_code[next_instr+2]) next_instr += 3 oparg = (oparg * 65536) | (hi * 256) | lo - opname = self.opnames[opcode] + if opnum in opcode.hasjrel: + oparg += next_instr + opname = self.opnames[opnum] return next_instr, opname, oparg @property diff --git a/rpython/flowspace/flowcontext.py b/rpython/flowspace/flowcontext.py --- a/rpython/flowspace/flowcontext.py +++ b/rpython/flowspace/flowcontext.py @@ -9,19 +9,16 @@ from rpython.tool.stdlib_opcode import host_bytecode_spec from rpython.flowspace.argument import CallSpec from rpython.flowspace.model import (Constant, Variable, Block, Link, - c_last_exception, SpaceOperation) + c_last_exception, SpaceOperation, const) from rpython.flowspace.framestate import (FrameState, recursively_unflatten, recursively_flatten) from rpython.flowspace.specialcase import (rpython_print_item, rpython_print_newline) -from rpython.flowspace.operation import op class FlowingError(Exception): """ Signals invalid RPython in the function being analysed""" - def __init__(self, frame, msg): - super(FlowingError, self).__init__(msg) - self.frame = frame + frame = None def __str__(self): msg = ["\n"] @@ -133,7 +130,7 @@ def append(self, operation): raise NotImplementedError - def guessbool(self, frame, w_condition, **kwds): + def guessbool(self, frame, w_condition): raise AssertionError("cannot guessbool(%s)" % (w_condition,)) @@ -215,7 +212,7 @@ [str(s) for s in self.listtoreplay[self.index:]])) self.index += 1 - def guessbool(self, frame, w_condition, **kwds): + def guessbool(self, frame, w_condition): assert self.index == len(self.listtoreplay) frame.recorder = self.nextreplayer return self.booloutcome @@ -309,7 +306,7 @@ def unsupportedoperation(OPCODE, msg): def UNSUPPORTED(self, *ignored): - raise FlowingError(self, "%s is not RPython" % (msg,)) + raise FlowingError("%s is not RPython" % (msg,)) UNSUPPORTED.func_name = OPCODE return UNSUPPORTED @@ -351,7 +348,7 @@ if closure is None: self.closure = [] else: - self.closure = [self.space.wrap(c.cell_contents) for c in closure] + self.closure = [const(c.cell_contents) for c in closure] assert len(self.closure) == len(self.pycode.co_freevars) def init_locals_stack(self, code): @@ -412,21 +409,7 @@ self.locals_stack_w[:len(items_w)] = items_w self.dropvaluesuntil(len(items_w)) - def unrollstack(self, unroller_kind): - while self.blockstack: - block = self.blockstack.pop() - if (block.handling_mask & unroller_kind) != 0: - return block - block.cleanupstack(self) - return None - - def unrollstack_and_jump(self, unroller): - block = self.unrollstack(unroller.kind) - if block is None: - raise BytecodeCorruption("misplaced bytecode - should not return") - return block.handle(self, unroller) - - def getstate(self): + def getstate(self, next_pos): # getfastscope() can return real None, for undefined locals data = self.save_locals_stack() if self.last_exception is None: @@ -435,42 +418,46 @@ else: data.append(self.last_exception.w_type) data.append(self.last_exception.w_value) - recursively_flatten(self.space, data) - return FrameState(data, self.blockstack[:], self.last_instr) + recursively_flatten(data) + return FrameState(data, self.blockstack[:], next_pos) def setstate(self, state): """ Reset the frame to the given state. """ data = state.mergeable[:] - recursively_unflatten(self.space, data) + recursively_unflatten(data) self.restore_locals_stack(data[:-2]) # Nones == undefined locals if data[-2] == Constant(None): assert data[-1] == Constant(None) self.last_exception = None else: self.last_exception = FSException(data[-2], data[-1]) - self.last_instr = state.next_instr self.blockstack = state.blocklist[:] - def guessbool(self, w_condition, **kwds): - return self.recorder.guessbool(self, w_condition, **kwds) + def guessbool(self, w_condition): + if isinstance(w_condition, Constant): + return w_condition.value + return self.recorder.guessbool(self, w_condition) def do_operation(self, name, *args_w): + spaceop = SpaceOperation(name, args_w, Variable()) + self.record(spaceop) + return spaceop.result + + def record(self, spaceop): recorder = self.recorder if getattr(recorder, 'final_state', None) is not None: self.mergeblock(recorder.crnt_block, recorder.final_state) raise StopFlowing - spaceop = SpaceOperation(name, args_w, Variable()) spaceop.offset = self.last_instr recorder.append(spaceop) - return spaceop.result - def do_operation_with_implicit_exceptions(self, name, *args_w): - w_result = self.do_operation(name, *args_w) - oper = getattr(op, name) - self.handle_implicit_exceptions(oper.canraise) - return w_result + def do_op(self, op): + self.record(op) + if op.canraise: + self.guessexception(op.canraise) + return op.result - def handle_implicit_exceptions(self, exceptions): + def guessexception(self, exceptions, force=False): """ Catch possible exceptions implicitly. @@ -479,9 +466,12 @@ even if the interpreter re-raises the exception, it will not be the same ImplicitOperationError instance internally. """ - if not exceptions: From noreply at buildbot.pypy.org Wed Sep 4 13:13:37 2013 From: noreply at buildbot.pypy.org (Manuel Jacob) Date: Wed, 4 Sep 2013 13:13:37 +0200 (CEST) Subject: [pypy-commit] pypy refactor-translator: hg merge default Message-ID: <20130904111337.804861C135D@cobra.cs.uni-duesseldorf.de> Author: Manuel Jacob Branch: refactor-translator Changeset: r66783:38845f2aeea8 Date: 2013-09-03 01:17 +0100 http://bitbucket.org/pypy/pypy/changeset/38845f2aeea8/ Log: hg merge default diff --git a/lib_pypy/_curses.py b/lib_pypy/_curses.py --- a/lib_pypy/_curses.py +++ b/lib_pypy/_curses.py @@ -1,6 +1,9 @@ """Reimplementation of the standard extension module '_curses' using cffi.""" import sys +if sys.platform == 'win32': + #This module does not exist in windows + raise ImportError('No module named _curses') from functools import wraps from cffi import FFI diff --git a/pypy/interpreter/pycode.py b/pypy/interpreter/pycode.py --- a/pypy/interpreter/pycode.py +++ b/pypy/interpreter/pycode.py @@ -254,7 +254,7 @@ if sys.version_info < (2, 7): raise Exception("PyPy no longer supports Python 2.6 or lower") from pypy.interpreter.pyframe import PyFrame - frame = PyFrame(self.space, self, w_globals, None) + frame = self.space.FrameClass(self.space, self, w_globals, None) frame.setdictscope(w_locals) return frame.run() 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 @@ -1516,13 +1516,18 @@ d = BStruct.fields assert d[0][1].offset == d[1][1].offset == d[2][1].offset == 0 assert d[3][1].offset == sizeof(BLong) - assert d[0][1].bitshift == 0 + def f(m, r): + if sys.byteorder == 'little': + return r + else: + return LONGBITS - m - r + assert d[0][1].bitshift == f(1, 0) assert d[0][1].bitsize == 1 - assert d[1][1].bitshift == 1 + assert d[1][1].bitshift == f(2, 1) assert d[1][1].bitsize == 2 - assert d[2][1].bitshift == 3 + assert d[2][1].bitshift == f(3, 3) assert d[2][1].bitsize == 3 - assert d[3][1].bitshift == 0 + assert d[3][1].bitshift == f(LONGBITS - 5, 0) assert d[3][1].bitsize == LONGBITS - 5 assert sizeof(BStruct) == 2 * sizeof(BLong) assert alignof(BStruct) == alignof(BLong) @@ -2856,7 +2861,7 @@ ('b1', BInt, 9), ('b2', BUInt, 7), ('c', BChar, -1)], -1, -1, -1, flag) - if flag % 2 == 0: # gcc and gcc ARM + if flag % 2 == 0: # gcc, any variant assert typeoffsetof(BStruct, 'c') == (BChar, 3) assert sizeof(BStruct) == 4 else: # msvc @@ -2864,6 +2869,31 @@ assert sizeof(BStruct) == 12 assert alignof(BStruct) == 4 # + p = newp(new_pointer_type(BStruct), None) + p.a = b'A' + p.b1 = -201 + p.b2 = 99 + p.c = b'\x9D' + raw = buffer(p)[:] + if sys.byteorder == 'little': + if flag == 0 or flag == 2: # gcc, little endian + assert raw == b'A7\xC7\x9D' + elif flag == 1: # msvc + assert raw == b'A\x00\x00\x007\xC7\x00\x00\x9D\x00\x00\x00' + elif flag == 4: # gcc, big endian + assert raw == b'A\xE3\x9B\x9D' + else: + raise AssertionError("bad flag") + else: + if flag == 0 or flag == 2: # gcc + assert raw == b'A\xC77\x9D' + elif flag == 1: # msvc + assert raw == b'A\x00\x00\x00\x00\x00\xC77\x9D\x00\x00\x00' + elif flag == 4: # gcc, big endian + assert raw == b'A\x9B\xE3\x9D' + else: + raise AssertionError("bad flag") + # BStruct = new_struct_type("struct foo2") complete_struct_or_union(BStruct, [('a', BChar, -1), ('', BShort, 9), @@ -2875,16 +2905,21 @@ elif flag == 1: # msvc assert sizeof(BStruct) == 6 assert alignof(BStruct) == 2 - else: # gcc ARM + elif flag == 2: # gcc ARM assert sizeof(BStruct) == 6 assert alignof(BStruct) == 2 + elif flag == 4: # gcc, big endian + assert sizeof(BStruct) == 5 + assert alignof(BStruct) == 1 + else: + raise AssertionError("bad flag") # BStruct = new_struct_type("struct foo2") complete_struct_or_union(BStruct, [('a', BChar, -1), ('', BInt, 0), ('', BInt, 0), ('c', BChar, -1)], -1, -1, -1, flag) - if flag == 0: # gcc + if flag == 0: # gcc assert typeoffsetof(BStruct, 'c') == (BChar, 4) assert sizeof(BStruct) == 5 assert alignof(BStruct) == 1 @@ -2892,10 +2927,16 @@ assert typeoffsetof(BStruct, 'c') == (BChar, 1) assert sizeof(BStruct) == 2 assert alignof(BStruct) == 1 - else: # gcc ARM + elif flag == 2: # gcc ARM assert typeoffsetof(BStruct, 'c') == (BChar, 4) assert sizeof(BStruct) == 8 assert alignof(BStruct) == 4 + elif flag == 4: # gcc, big endian + assert typeoffsetof(BStruct, 'c') == (BChar, 4) + assert sizeof(BStruct) == 5 + assert alignof(BStruct) == 1 + else: + raise AssertionError("bad flag") def test_bitfield_as_gcc(): @@ -2907,6 +2948,11 @@ def test_bitfield_as_arm_gcc(): _test_bitfield_details(flag=2) +def test_bitfield_as_big_endian(): + if '__pypy__' in sys.builtin_module_names: + py.test.skip("no big endian machine supported on pypy for now") + _test_bitfield_details(flag=4) + def test_version(): # this test is here mostly for PyPy 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 @@ -992,6 +992,7 @@ assert ret == 42 def test_pyc_magic_changes(self): + py.test.skip("For now, PyPy generates only one kind of .pyc files") # test that the pyc files produced by a space are not reimportable # from another, if they differ in what opcodes they support allspaces = [self.space] diff --git a/pypy/module/test_lib_pypy/test_curses.py b/pypy/module/test_lib_pypy/test_curses.py --- a/pypy/module/test_lib_pypy/test_curses.py +++ b/pypy/module/test_lib_pypy/test_curses.py @@ -1,4 +1,8 @@ import pytest +import sys +if sys.platform == 'win32': + #This module does not exist in windows + pytest.skip('no curses on windows') # Check that lib_pypy.cffi finds the correct version of _cffi_backend. # Otherwise, the test is skipped. It should never be skipped when run From noreply at buildbot.pypy.org Wed Sep 4 16:14:04 2013 From: noreply at buildbot.pypy.org (alex_gaynor) Date: Wed, 4 Sep 2013 16:14:04 +0200 (CEST) Subject: [pypy-commit] pypy default: A passing test for yesterday's "Inline into thread" commit Message-ID: <20130904141404.4846B1C0205@cobra.cs.uni-duesseldorf.de> Author: Alex Gaynor Branch: Changeset: r66784:836ba1df33a1 Date: 2013-09-04 07:13 -0700 http://bitbucket.org/pypy/pypy/changeset/836ba1df33a1/ Log: A passing test for yesterday's "Inline into thread" commit 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 @@ -48,3 +48,47 @@ i58 = arraylen_gc(p43, descr=...) jump(..., descr=...) """) + + def test_lock_acquire_release(self): + def main(n): + import threading + lock = threading.Lock() + while n > 0: + with lock: + n -= 1 + log = self.run(main, [500]) + assert log.result == main(500) + loop, = log.loops_by_filename(self.filepath) + assert loop.match(""" + i58 = int_gt(i43, 0) + guard_true(i58, descr=) + p59 = getfield_gc(p15, descr=) + i60 = getfield_gc(p59, descr=) + p61 = force_token() + setfield_gc(p0, p61, descr=) + i62 = call_release_gil(4312440032, i60, 1, descr=) + guard_not_forced(descr=) + guard_no_exception(descr=) + i63 = int_is_true(i62) + guard_true(i63, descr=) + i64 = int_sub(i43, 1) + guard_not_invalidated(descr=) + p66 = getfield_gc(p15, descr=) + i67 = getfield_gc(p66, descr=) + p68 = force_token() + setfield_gc(p0, p68, descr=) + i69 = call_release_gil(4312440032, i67, 0, descr=) + guard_not_forced(descr=) + guard_no_exception(descr=) + i70 = int_is_true(i69) + guard_false(i70, descr=) + i71 = getfield_gc(p66, descr=) + p72 = force_token() + setfield_gc(p0, p72, descr=) + call_release_gil(4312441056, i71, descr=) + guard_not_forced(descr=) + guard_no_exception(descr=) + guard_not_invalidated(descr=) + --TICK-- + jump(..., descr=TargetToken(4361239720)) + """) From noreply at buildbot.pypy.org Thu Sep 5 10:29:08 2013 From: noreply at buildbot.pypy.org (arigo) Date: Thu, 5 Sep 2013 10:29:08 +0200 (CEST) Subject: [pypy-commit] pypy default: We must setup the GIL here, in case the callback is invoked in some Message-ID: <20130905082908.91ED11C0EE9@cobra.cs.uni-duesseldorf.de> Author: Armin Rigo Branch: Changeset: r66785:0e638a269c11 Date: 2013-09-03 16:47 +0200 http://bitbucket.org/pypy/pypy/changeset/0e638a269c11/ Log: We must setup the GIL here, in case the callback is invoked in some other non-Pythonic thread. This is the same as cffi on CPython. This should fix the shadowstack failure of test_callback_in_thread. diff --git a/pypy/module/_cffi_backend/ccallback.py b/pypy/module/_cffi_backend/ccallback.py --- a/pypy/module/_cffi_backend/ccallback.py +++ b/pypy/module/_cffi_backend/ccallback.py @@ -54,6 +54,13 @@ if rffi.cast(lltype.Signed, res) != clibffi.FFI_OK: raise OperationError(space.w_SystemError, space.wrap("libffi failed to build this callback")) + # + # We must setup the GIL here, in case the callback is invoked in + # some other non-Pythonic thread. This is the same as cffi on + # CPython. + if space.config.translation.thread: + from pypy.module.thread.os_thread import setup_threads + setup_threads(space) def get_closure(self): return rffi.cast(clibffi.FFI_CLOSUREP, self._cdata) From noreply at buildbot.pypy.org Thu Sep 5 10:29:10 2013 From: noreply at buildbot.pypy.org (arigo) Date: Thu, 5 Sep 2013 10:29:10 +0200 (CEST) Subject: [pypy-commit] pypy stmgc-c4: Remove this test, not working any more since a while Message-ID: <20130905082910.CA08C1C36AC@cobra.cs.uni-duesseldorf.de> Author: Armin Rigo Branch: stmgc-c4 Changeset: r66786:ab2876bee9a3 Date: 2013-09-04 15:39 +0200 http://bitbucket.org/pypy/pypy/changeset/ab2876bee9a3/ Log: Remove this test, not working any more since a while diff --git a/rpython/translator/stm/test/test_stmgcintf.c b/rpython/translator/stm/test/test_stmgcintf.c deleted file mode 100644 --- a/rpython/translator/stm/test/test_stmgcintf.c +++ /dev/null @@ -1,415 +0,0 @@ -#define _GNU_SOURCE -#define _XOPEN_SOURCE 500 - -#include - -#define PYPY_LONG_BIT (sizeof(long) * 8) - -typedef long Signed; -typedef unsigned long Unsigned; - -struct pypy_header0 { - long h_tid; - Unsigned h_revision; - Unsigned h_original; -}; - -struct pypy_pypy_rlib_rstm_Transaction0 { - struct pypy_header0 header; - struct pypy_pypy_rlib_rstm_Transaction0 *t_inst__next_transaction; - void *stack_root_top; - int foobar; - void (*callback)(void); - void *stack_roots[3]; -}; - -typedef struct { - struct pypy_header0 header; - char value1; -} S1; - -typedef char bool_t; -typedef char RPyString; - -#define _RPyString_AsString(x) x -#define RPyString_Size(x) strlen(x) - -#include "src_stm/stmgc.h" -#include "src_stm/stmimpl.h" -#include "src_stm/et.h" -#include "src_stm/et.c" - - -gcptr (*cb_duplicate)(gcptr); -void (*cb_enum_callback)(void *, gcptr); - -void *pypy_g__stm_duplicate(void *a) { - assert(cb_duplicate != NULL); - return cb_duplicate((gcptr)a); -} -void pypy_g__stm_enum_callback(void *a, void *b) { - assert(cb_enum_callback != NULL); - cb_enum_callback(a, (gcptr)b); -} - - -static long rt2(void *t1, long retry_counter) -{ - struct pypy_pypy_rlib_rstm_Transaction0 *t = t1; - if (retry_counter > 0) { - t->foobar = retry_counter; - return 0; - } - t->callback(); - t->foobar = '.'; - return 0; -} -void run_in_transaction(void(*cb)(void), int expected) -{ - struct pypy_pypy_rlib_rstm_Transaction0 t; - t.stack_root_top = t.stack_roots; - t.callback = cb; - stm_perform_transaction(rt2, &t, &t.stack_root_top); - assert(t.foobar == expected); -} - -/************************************************************/ - -void test_bool_cas(void) -{ - volatile Unsigned bv = 10; - - assert(bool_cas(&bv, 10, 15)); - assert(bv == 15); - assert(!bool_cas(&bv, 10, 15)); - assert(bv == 15); - assert(!bool_cas(&bv, 10, 25)); - assert(bv == 15); - assert(bool_cas(&bv, 15, 14)); - assert(bv == 14); -} - -void test_fetch_and_add(void) -{ - volatile Unsigned bv = 14; - - assert(fetch_and_add(&bv, 2) == 14); - assert(bv == 16); - assert(fetch_and_add(&bv, 7) == 16); - assert(fetch_and_add(&bv, (Unsigned)-1) == 23); - assert(bv == 22); -} - -/************************************************************/ - -void test_set_get_del(void) -{ - stm_set_tls((void *)42); - assert(stm_get_tls() == (void *)42); - stm_del_tls(); -} - -/************************************************************/ - -static long rt1(void *t1, long retry_counter) -{ - struct pypy_pypy_rlib_rstm_Transaction0 *t = t1; - assert(retry_counter == 0); - assert(t->foobar == 42); - assert(t->stack_root_top == t->stack_roots + 1); - assert(t->stack_roots[0] == (void*)-8); /* END_MARKER */ - assert(t->stack_roots[1] == (void*)43); - assert(t->stack_roots[2] == (void*)44); - t->foobar = 143; - return 0; -} -void test_run_all_transactions(void) -{ - struct pypy_pypy_rlib_rstm_Transaction0 t; - t.stack_root_top = t.stack_roots; - t.stack_roots[0] = (void*)42; - t.stack_roots[1] = (void*)43; - t.stack_roots[2] = (void*)44; - t.foobar = 42; - stm_perform_transaction(rt1, &t, &t.stack_root_top); - assert(t.foobar == 143); - assert(t.stack_root_top == t.stack_roots); -} - -/************************************************************/ - -void tldict(void) -{ - void *a1 = (void *)0x4020; - void *a2 = (void *)10002; - void *a3 = (void *)0x4028; - void *a4 = (void *)10004; - - assert(stm_tldict_lookup(a1) == NULL); - stm_tldict_add(a1, a2); - assert(stm_tldict_lookup(a1) == a2); - - assert (stm_tldict_lookup(a3) == NULL); - stm_tldict_add(a3, a4); - assert(stm_tldict_lookup(a3) == a4); - assert(stm_tldict_lookup(a1) == a2); - stm_abort_and_retry(); -} -void test_tldict(void) { run_in_transaction(tldict, 1); } - -/************************************************************/ - -void tldict_large(void) -{ - void *content[4096] = { 0 }; - int i; - for (i=0; i<120000; i++) { - long key_index = rand() & 4095; - void *a1 = (void *)(10000 + key_index * 8); - void *a2 = stm_tldict_lookup(a1); - - if (content[key_index] != NULL) { - assert(a2 == content[key_index]); - } - else { - assert(a2 == NULL); - while (a2 == NULL) - a2 = (void *)rand(); - stm_tldict_add(a1, a2); - content[key_index] = a2; - } - } - stm_abort_and_retry(); -} -void test_tldict_large(void) { run_in_transaction(tldict_large, 1); } - -/************************************************************/ - -void enum_tldict_empty(void) -{ - stm_tldict_enum(); -} -void test_enum_tldict_empty(void) { - run_in_transaction(enum_tldict_empty, '.'); } - -/************************************************************/ - -struct pypy_header0 etldn1 = {GCFLAG_PREBUILT, REV_INITIAL}; -struct pypy_header0 etldn2 = {GCFLAG_LOCAL_COPY, (revision_t)&etldn1}; -struct pypy_header0 etldn3 = {GCFLAG_PREBUILT, REV_INITIAL}; -struct pypy_header0 etldn4 = {GCFLAG_LOCAL_COPY, (revision_t)&etldn3}; - -int check_enum_1_found; -void check_enum_1(void *tls, gcptr b) -{ - int n; - gcptr a = (gcptr)b->h_revision; - assert(tls == (void *)742); - if (a == &etldn1 && b == &etldn2) - n = 1; - else if (a == &etldn3 && b == &etldn4) - n = 2; - else - assert(!"unexpected a or b"); - assert((check_enum_1_found & n) == 0); - check_enum_1_found |= n; -} -void enum_tldict_nonempty(void) -{ - stm_set_tls((void *)742); - stm_tldict_add(&etldn1, &etldn2); - stm_tldict_add(&etldn3, &etldn4); - cb_enum_callback = check_enum_1; - check_enum_1_found = 0; - stm_tldict_enum(); - assert(check_enum_1_found == (1|2)); - stm_abort_and_retry(); -} -void test_enum_tldict_nonempty(void) { - run_in_transaction(enum_tldict_nonempty, 1); } - -/************************************************************/ - -void test_read_main_thread(void) -{ - S1 s1; - S1 *p2; - int i; - BeginInevitableTransaction(); - for (i=0; i<2; i++) { - s1.header.h_tid = GCFLAG_PREBUILT | (i ? GCFLAG_POSSIBLY_OUTDATED : 0); - s1.header.h_revision = REV_INITIAL; - - p2 = STM_BARRIER_P2R(&s1); - assert(p2 == &s1); - - p2 = STM_BARRIER_G2R(&s1); - assert(p2 == &s1); - } -} - -/************************************************************/ - -void read_transaction(void) -{ - S1 s1, s2; - S1 *p2; - int i; - for (i=0; i<2; i++) { - s1.header.h_tid = GCFLAG_PREBUILT | (i ? GCFLAG_POSSIBLY_OUTDATED : 0); - s1.header.h_revision = REV_INITIAL; - - p2 = STM_BARRIER_P2R(&s1); - assert(p2 == &s1); - - p2 = STM_BARRIER_G2R(&s1); - assert(p2 == &s1); - } - - s1.header.h_tid = GCFLAG_PREBUILT | GCFLAG_POSSIBLY_OUTDATED; - s1.header.h_revision = REV_INITIAL; - s2.header.h_tid = GCFLAG_LOCAL_COPY; - s2.header.h_revision = (revision_t)&s1; - stm_tldict_add(&s1.header, &s2.header); - - p2 = STM_BARRIER_P2R(&s1); - assert(p2 == &s2); - - p2 = STM_BARRIER_G2R(&s1); - assert(p2 == &s2); - - p2 = STM_BARRIER_O2R(&s1); - assert(p2 == &s2); - - p2 = STM_BARRIER_P2R(&s2); - assert(p2 == &s2); - - p2 = STM_BARRIER_O2R(&s2); - assert(p2 == &s2); - - stm_abort_and_retry(); -} -void test_read_transaction(void) { run_in_transaction(read_transaction, 1); } - -/************************************************************/ - -int sg_seen = 0; -S1 sg_global, sg_local; -void duplicator(void) -{ - S1 *s2; - int i; - sg_global.header.h_tid = GCFLAG_PREBUILT | GCFLAG_POSSIBLY_OUTDATED; - sg_global.header.h_revision = REV_INITIAL; - sg_global.value1 = 123; - - s2 = STM_BARRIER_P2W(&sg_global); - assert(s2 == &sg_local); - assert(s2->header.h_tid == GCFLAG_LOCAL_COPY | GCFLAG_VISITED); - assert(s2->header.h_revision == (revision_t)&sg_global); - assert(s2->value1 == 123); -} -gcptr duplicator_cb(gcptr x) -{ - assert(x == &sg_global.header); - sg_local = sg_global; - sg_local.header.h_tid &= ~(GCFLAG_GLOBAL | GCFLAG_POSSIBLY_OUTDATED); - sg_local.header.h_tid |= GCFLAG_LOCAL_COPY | GCFLAG_VISITED; - return &sg_local.header; -} -void test_duplicator(void) -{ - cb_duplicate = duplicator_cb; - run_in_transaction(duplicator, '.'); -} - -/************************************************************/ - -void try_inevitable(void) -{ - assert(stm_in_transaction() == 1); - assert(!stm_is_inevitable()); - /* not really testing anything more than the presence of the function */ - BecomeInevitable("some explanation"); - assert(stm_is_inevitable()); -} -void test_try_inevitable(void) -{ - assert(stm_in_transaction() == 0); - run_in_transaction(try_inevitable, '.'); -} - -/************************************************************/ - -void should_break_transaction_1(void) -{ - assert(stm_should_break_transaction() == 0); - stm_set_transaction_length(10); /* implies "becomes inevitable" */ - assert(stm_should_break_transaction() == 1); -} - -void should_break_transaction_2(void) -{ - S1 s1[15]; - int i; - for (i=0; i<15; i++) { - s1[i].header.h_tid = GCFLAG_PREBUILT; - s1[i].header.h_revision = REV_INITIAL; - s1[i].value1 = 48+i; - } - for (i=0; i<15; i++) { - S1 *p = STM_BARRIER_P2R(&s1[i]); - assert(p->value1 == 48+i); - assert(stm_should_break_transaction() == ((i+1) >= 10)); - } -} - -void test_should_break_transaction(void) -{ - assert(stm_in_transaction() == 0); - run_in_transaction(should_break_transaction_1, '.'); - run_in_transaction(should_break_transaction_2, '.'); -} - -/************************************************************/ - -void single_thread_1(void) -{ - stm_start_single_thread(); - stm_stop_single_thread(); - stm_start_single_thread(); - stm_stop_single_thread(); - /* check that the assert() included in these functions don't trigger */ -} - -void test_single_thread(void) -{ - run_in_transaction(single_thread_1, '.'); -} - -/************************************************************/ - - -#define XTEST(name) if (!strcmp(argv[1], #name)) { test_##name(); return 0; } - -int main(int argc, char **argv) -{ - XTEST(bool_cas); - XTEST(fetch_and_add); - - DescriptorInit(); - XTEST(set_get_del); - XTEST(run_all_transactions); - XTEST(tldict); - XTEST(tldict_large); - XTEST(enum_tldict_empty); - XTEST(enum_tldict_nonempty); - XTEST(read_main_thread); - XTEST(read_transaction); - XTEST(duplicator); - XTEST(try_inevitable); - XTEST(should_break_transaction); - XTEST(single_thread); - printf("bad test name\n"); - return 1; -} diff --git a/rpython/translator/stm/test/test_stmgcintf.py b/rpython/translator/stm/test/test_stmgcintf.py deleted file mode 100644 --- a/rpython/translator/stm/test/test_stmgcintf.py +++ /dev/null @@ -1,27 +0,0 @@ -import os -from rpython.tool.udir import udir - - -def test_all(): - executable = str(udir.join('test_stmgcintf')) - prevdir = os.getcwd() - thisdir = os.path.dirname(__file__) - try: - os.chdir(thisdir) - exitcode = os.system( - "gcc -lrt -g -o '%s' -pthread -I.. test_stmgcintf.c" % ( - executable,)) - assert exitcode == 0 - finally: - os.chdir(prevdir) - # - for line in open(os.path.join(thisdir, 'test_stmgcintf.c')): - line = line.strip() - if line.startswith('XTEST('): - assert line.endswith(');') - yield run_one_test, executable, line[6:-2] - - -def run_one_test(executable, testname): - exitcode = os.system("'%s' %s" % (executable, testname)) - assert exitcode == 0, "exitcode is %r running %r" % (exitcode, testname) From noreply at buildbot.pypy.org Thu Sep 5 10:29:12 2013 From: noreply at buildbot.pypy.org (arigo) Date: Thu, 5 Sep 2013 10:29:12 +0200 (CEST) Subject: [pypy-commit] pypy default: merge heads Message-ID: <20130905082912.005081C36AE@cobra.cs.uni-duesseldorf.de> Author: Armin Rigo Branch: Changeset: r66787:c99baebdd2f2 Date: 2013-09-05 10:28 +0200 http://bitbucket.org/pypy/pypy/changeset/c99baebdd2f2/ Log: merge heads 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 @@ -109,7 +109,8 @@ 'posix', '_socket', '_sre', '_lsprof', '_weakref', '__pypy__', 'cStringIO', '_collections', 'struct', 'mmap', 'marshal', '_codecs', 'rctime', 'cppyy', - '_cffi_backend', 'pyexpat', '_continuation', '_io']: + '_cffi_backend', 'pyexpat', '_continuation', '_io', + 'thread']: if modname == 'pypyjit' and 'interp_resop' in rest: return False return True diff --git a/pypy/module/pypyjit/test/test_policy.py b/pypy/module/pypyjit/test/test_policy.py --- a/pypy/module/pypyjit/test/test_policy.py +++ b/pypy/module/pypyjit/test/test_policy.py @@ -45,6 +45,10 @@ from pypy.module._io.interp_bytesio import W_BytesIO assert pypypolicy.look_inside_function(W_BytesIO.seek_w.im_func) +def test_thread(): + from pypy.module.thread.os_lock import Lock + assert pypypolicy.look_inside_function(Lock.descr_lock_acquire.im_func) + def test_pypy_module(): from pypy.module._collections.interp_deque import W_Deque from pypy.module._random.interp_random import W_Random 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 @@ -48,3 +48,47 @@ i58 = arraylen_gc(p43, descr=...) jump(..., descr=...) """) + + def test_lock_acquire_release(self): + def main(n): + import threading + lock = threading.Lock() + while n > 0: + with lock: + n -= 1 + log = self.run(main, [500]) + assert log.result == main(500) + loop, = log.loops_by_filename(self.filepath) + assert loop.match(""" + i58 = int_gt(i43, 0) + guard_true(i58, descr=) + p59 = getfield_gc(p15, descr=) + i60 = getfield_gc(p59, descr=) + p61 = force_token() + setfield_gc(p0, p61, descr=) + i62 = call_release_gil(4312440032, i60, 1, descr=) + guard_not_forced(descr=) + guard_no_exception(descr=) + i63 = int_is_true(i62) + guard_true(i63, descr=) + i64 = int_sub(i43, 1) + guard_not_invalidated(descr=) + p66 = getfield_gc(p15, descr=) + i67 = getfield_gc(p66, descr=) + p68 = force_token() + setfield_gc(p0, p68, descr=) + i69 = call_release_gil(4312440032, i67, 0, descr=) + guard_not_forced(descr=) + guard_no_exception(descr=) + i70 = int_is_true(i69) + guard_false(i70, descr=) + i71 = getfield_gc(p66, descr=) + p72 = force_token() + setfield_gc(p0, p72, descr=) + call_release_gil(4312441056, i71, descr=) + guard_not_forced(descr=) + guard_no_exception(descr=) + guard_not_invalidated(descr=) + --TICK-- + jump(..., descr=TargetToken(4361239720)) + """) From noreply at buildbot.pypy.org Thu Sep 5 11:52:32 2013 From: noreply at buildbot.pypy.org (arigo) Date: Thu, 5 Sep 2013 11:52:32 +0200 (CEST) Subject: [pypy-commit] pypy stmgc-c4: Fix? But the test is still failing Message-ID: <20130905095232.CDE871C371B@cobra.cs.uni-duesseldorf.de> Author: Armin Rigo Branch: stmgc-c4 Changeset: r66789:5e04dcac213c Date: 2013-09-05 11:51 +0200 http://bitbucket.org/pypy/pypy/changeset/5e04dcac213c/ Log: Fix? But the test is still failing diff --git a/rpython/jit/backend/x86/test/test_stm_integration.py b/rpython/jit/backend/x86/test/test_stm_integration.py --- a/rpython/jit/backend/x86/test/test_stm_integration.py +++ b/rpython/jit/backend/x86/test/test_stm_integration.py @@ -422,7 +422,7 @@ ] inputargs = [p0] looptoken = JitCellToken() - cpu.compile_loop(inputargs, operations, looptoken) + cpu.compile_loop(None, inputargs, operations, looptoken) self.cpu.execute_token(looptoken, sgcref) # check if rev-fastpath worked @@ -465,7 +465,7 @@ ] inputargs = [p0] looptoken = JitCellToken() - cpu.compile_loop(inputargs, operations, looptoken) + cpu.compile_loop(None, inputargs, operations, looptoken) self.cpu.execute_token(looptoken, sgcref) # check if rev-fastpath worked @@ -536,8 +536,8 @@ inputargs = [p for p in (p1, p2) if not isinstance(p, Const)] looptoken = JitCellToken() - c_loop = cpu.compile_loop(inputargs + [i1], operations, - looptoken) + c_loop = cpu.compile_loop(None, inputargs + [i1], + operations, looptoken) args = [s for i, s in enumerate((s1, s2)) if not isinstance((p1, p2)[i], Const)] + [7] @@ -614,7 +614,7 @@ looptoken.outermost_jitdriver_sd = FakeJitDriverSD() finish_descr = loop.operations[-1].getdescr() self.cpu.done_with_this_frame_descr_int = BasicFinalDescr() - self.cpu.compile_loop(loop.inputargs, loop.operations, looptoken) + self.cpu.compile_loop(None, loop.inputargs, loop.operations, looptoken) ARGS = [lltype.Signed] * 10 RES = lltype.Signed FakeJitDriverSD.portal_calldescr = self.cpu.calldescrof( @@ -632,7 +632,8 @@ ''' loop = parse(ops, namespace=locals()) othertoken = JitCellToken() - self.cpu.compile_loop(loop.inputargs, loop.operations, othertoken) + self.cpu.compile_loop(None, loop.inputargs, loop.operations, + othertoken) args = [i+1 for i in range(10)] deadframe = self.cpu.execute_token(othertoken, *args) assert called == [id(finish_descr)] @@ -654,7 +655,8 @@ loop2 = parse(ops) looptoken2 = JitCellToken() looptoken2.outermost_jitdriver_sd = FakeJitDriverSD() - self.cpu.compile_loop(loop2.inputargs, loop2.operations, looptoken2) + self.cpu.compile_loop(None, loop2.inputargs, loop2.operations, + looptoken2) finish_descr2 = loop2.operations[-1].getdescr() # install it @@ -686,7 +688,7 @@ inputargs = [] looptoken = JitCellToken() - c_loop = cpu.compile_loop(inputargs, ops1, + c_loop = cpu.compile_loop(None, inputargs, ops1, looptoken) args = [] @@ -739,7 +741,7 @@ inputargs = [i0] looptoken = JitCellToken() looptoken.outermost_jitdriver_sd = FakeJitDriverSD() - c_loop = cpu.compile_loop(inputargs, ops, looptoken) + c_loop = cpu.compile_loop(None, inputargs, ops, looptoken) print "\n".join(map(str,c_loop[1])) ARGS = [lltype.Signed] * 10 @@ -763,7 +765,7 @@ ] othertoken = JitCellToken() cpu.done_with_this_frame_descr_int = BasicFinalDescr() - c_loop = cpu.compile_loop([], ops, othertoken) + c_loop = cpu.compile_loop(None, [], ops, othertoken) print "\n".join(map(str,c_loop[1])) deadframe = cpu.execute_token(othertoken) @@ -814,7 +816,7 @@ ] inputargs = [p0] looptoken = JitCellToken() - print cpu.compile_loop(inputargs, operations, looptoken) + print cpu.compile_loop(None, inputargs, operations, looptoken) cpu.execute_token(looptoken, sgcref) # the second write-barrier must see the result of the From noreply at buildbot.pypy.org Thu Sep 5 11:52:31 2013 From: noreply at buildbot.pypy.org (arigo) Date: Thu, 5 Sep 2013 11:52:31 +0200 (CEST) Subject: [pypy-commit] pypy stmgc-c4: hg merge default Message-ID: <20130905095231.9564A1C36AE@cobra.cs.uni-duesseldorf.de> Author: Armin Rigo Branch: stmgc-c4 Changeset: r66788:2f0998157e32 Date: 2013-09-05 11:45 +0200 http://bitbucket.org/pypy/pypy/changeset/2f0998157e32/ Log: hg merge default Lots of changes, needs careful testing diff too long, truncating to 2000 out of 81120 lines diff --git a/LICENSE b/LICENSE --- a/LICENSE +++ b/LICENSE @@ -2,9 +2,9 @@ ======= Except when otherwise stated (look for LICENSE files in directories or -information at the beginning of each file) all software and -documentation in the 'pypy', 'ctype_configure', 'dotviewer', 'demo', -and 'lib_pypy' directories is licensed as follows: +information at the beginning of each file) all software and documentation in +the 'rpython', 'pypy', 'ctype_configure', 'dotviewer', 'demo', and 'lib_pypy' +directories is licensed as follows: The MIT License @@ -38,176 +38,239 @@ Armin Rigo Maciej Fijalkowski Carl Friedrich Bolz + Antonio Cuni Amaury Forgeot d'Arc - Antonio Cuni Samuele Pedroni + Alex Gaynor Michael Hudson + David Schneider Holger Krekel - Alex Gaynor Christian Tismer Hakan Ardo Benjamin Peterson - David Schneider + Matti Picus + Philip Jenvey + Anders Chrigstrom + Brian Kearns Eric van Riet Paap - Anders Chrigstrom Richard Emslie + Alexander Schremmer + Wim Lavrijsen Dan Villiom Podlaski Christiansen - Alexander Schremmer + Manuel Jacob Lukas Diekmann + Sven Hager + Anders Lehmann Aurelien Campeas - Anders Lehmann + Niklaus Haldimann + Ronan Lamy Camillo Bruni - Niklaus Haldimann - Sven Hager + Laura Creighton + Toon Verwaest Leonardo Santagada - Toon Verwaest Seo Sanghyeon Justin Peel + Ronny Pfannschmidt + David Edelsohn + Anders Hammarquist + Jakub Gustak + Guido Wesdorp Lawrence Oluyede Bartosz Skowron - Jakub Gustak - Guido Wesdorp Daniel Roberts - Laura Creighton + Niko Matsakis Adrien Di Mascio Ludovic Aubry - Niko Matsakis - Wim Lavrijsen - Matti Picus + Alexander Hesse + Jacob Hallen + Romain Guillebert Jason Creighton - Jacob Hallen Alex Martelli - Anders Hammarquist + Michal Bendowski Jan de Mooij + Michael Foord Stephan Diehl - Michael Foord Stefan Schwarzer + Valentino Volonghi Tomek Meka Patrick Maupin + stian Bob Ippolito Bruno Gola + Jean-Paul Calderone + Timo Paulssen Alexandre Fayolle + Simon Burton Marius Gedminas - Simon Burton - David Edelsohn - Jean-Paul Calderone John Witulski - Timo Paulssen - holger krekel + Greg Price Dario Bertini Mark Pearse + Simon Cross + Konstantin Lopuhin Andreas Stührk Jean-Philippe St. Pierre Guido van Rossum Pavel Vinogradov - Valentino Volonghi Paul deGrandis Ilya Osadchiy - Ronny Pfannschmidt Adrian Kuhn + Boris Feigin tav Georg Brandl - Philip Jenvey + Bert Freudenberg + Stian Andreassen + Stefano Rivera + Wanja Saatkamp Gerald Klix - Wanja Saatkamp - Boris Feigin + Mike Blume + Taavi Burns Oscar Nierstrasz David Malcolm Eugene Oden Henry Mason + Preston Timmons Jeff Terrace + David Ripton + Dusty Phillips Lukas Renggli Guenter Jantzen + Tobias Oberstein + Remi Meier Ned Batchelder - Bert Freudenberg Amit Regmi Ben Young Nicolas Chauvat Andrew Durdin Michael Schneider Nicholas Riley + Jason Chu + Igor Trindade Oliveira + Jeremy Thurgood Rocco Moretti Gintautas Miliauskas Michael Twomey - Igor Trindade Oliveira Lucian Branescu Mihaila + Tim Felgentreff + Tyler Wade + Gabriel Lavoie Olivier Dormond Jared Grubb Karl Bartel - Gabriel Lavoie + Brian Dorsey Victor Stinner - Brian Dorsey Stuart Williams + Jasper Schulz Toby Watson Antoine Pitrou + Aaron Iles + Michael Cheng Justas Sadzevicius + Gasper Zejn Neil Shepperd Mikael Schönenberg - Gasper Zejn + Elmo Mäntynen + Tobias Pape Jonathan David Riehl - Elmo Mäntynen + Stanislaw Halik Anders Qvist + Chirag Jadwani Beatrice During + Alex Perry + Vincent Legoll + Alan McIntyre Alexander Sedov Corbin Simpson - Vincent Legoll - Romain Guillebert - Alan McIntyre - Alex Perry + Christopher Pope + Laurence Tratt + Guillebert Romain + Christian Tismer + Dan Stromberg + Stefano Parmesan + Christian Hudon + Alexis Daboville Jens-Uwe Mager - Simon Cross - Dan Stromberg - Guillebert Romain Carl Meyer + Karl Ramm Pieter Zieschang + Gabriel + Paweł Piotr Przeradowski + Andrew Dalke + Sylvain Thenault + Nathan Taylor + Vladimir Kryachko + Jacek Generowicz Alejandro J. Cura - Sylvain Thenault - Christoph Gerum + Jacob Oscarson Travis Francis Athougies + Kristjan Valur Jonsson + Neil Blakey-Milner + Lutz Paelike + Lucio Torre + Lars Wassermann Henrik Vendelbo - Lutz Paelike - Jacob Oscarson - Martin Blais - Lucio Torre - Lene Wagner + Dan Buch Miguel de Val Borro Artur Lisiecki - Bruno Gola + Sergey Kishchenko Ignas Mikalajunas - Stefano Rivera + Christoph Gerum + Martin Blais + Lene Wagner + Tomo Cocoa + Andrews Medina + roberto at goyle + William Leslie + Bobby Impollonia + timo at eistee.fritz.box + Andrew Thompson + Yusei Tahara + Roberto De Ioris + Juan Francisco Cantero Hurtado + Godefroid Chappelle Joshua Gilbert - Godefroid Chappelle - Yusei Tahara + Dan Colish Christopher Armstrong + Michael Hudson-Doyle + Anders Sigfridsson + Yasir Suhail + Floris Bruynooghe + Akira Li + Gustavo Niemeyer Stephan Busemann - Gustavo Niemeyer - William Leslie - Akira Li - Kristjan Valur Jonsson - Bobby Impollonia - Michael Hudson-Doyle - Laurence Tratt - Yasir Suhail - Andrew Thompson - Anders Sigfridsson - Floris Bruynooghe - Jacek Generowicz - Dan Colish - Zooko Wilcox-O Hearn - Dan Loewenherz + Anna Katrina Dominguez + Christian Muirhead + James Lan + shoma hosaka + Daniel Neuhäuser + Buck Golemon + Konrad Delong + Dinu Gherman Chris Lambacher - Dinu Gherman - Brett Cannon - Daniel Neuhäuser - Michael Chermside - Konrad Delong - Anna Ravencroft - Greg Price - Armin Ronacher - Christian Muirhead + coolbutuseless at gmail.com Jim Baker Rodrigo Araújo - Romain Guillebert + Armin Ronacher + Brett Cannon + yrttyr + Zooko Wilcox-O Hearn + Tomer Chachamu + Christopher Groskopf + opassembler.py + Antony Lee + Jim Hunziker + Markus Unterwaditzer + Even Wiik Thomassen + jbs + soareschen + Flavio Percoco + Kristoffer Kleine + yasirs + Michael Chermside + Anna Ravencroft + Andrew Chambers + Julien Phalip + Dan Loewenherz Heinrich-Heine University, Germany Open End AB (formerly AB Strakt), Sweden @@ -219,45 +282,21 @@ Change Maker, Sweden University of California Berkeley, USA Google Inc. + King's College London The PyPy Logo as used by http://speed.pypy.org and others was created by Samuel Reis and is distributed on terms of Creative Commons Share Alike License. -License for 'lib-python/2.7.0' and 'lib-python/2.7.0-modified' -============================================================== +License for 'lib-python/2.7' +============================ -Except when otherwise stated (look for LICENSE files or -copyright/license information at the beginning of each file) the files -in the 'lib-python/2.7.0' and 'lib-python/2.7.0-modified' directories -are all copyrighted by the Python Software Foundation and licensed under -the Python Software License of which you can find a copy here: +Except when otherwise stated (look for LICENSE files or copyright/license +information at the beginning of each file) the files in the 'lib-python/2.7' +directory are all copyrighted by the Python Software Foundation and licensed +under the Python Software License of which you can find a copy here: http://www.python.org/doc/Copyright.html -License for 'pypy/translator/jvm/src/jna.jar' -============================================= - -The file 'pypy/translator/jvm/src/jna.jar' is licensed under the GNU -Lesser General Public License of which you can find a copy here: -http://www.gnu.org/licenses/lgpl.html - -License for 'pypy/translator/jvm/src/jasmin.jar' -================================================ - -The file 'pypy/translator/jvm/src/jasmin.jar' is copyright (c) 1996-2004 Jon Meyer -and distributed with permission. The use of Jasmin by PyPy does not imply -that PyPy is endorsed by Jon Meyer nor any of Jasmin's contributors. Furthermore, -the following disclaimer applies to Jasmin: - -THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED -WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A -PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR -ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT -LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS -INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR -TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF -ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - License for 'pypy/module/unicodedata/' ====================================== diff --git a/dotviewer/drawgraph.py b/dotviewer/drawgraph.py --- a/dotviewer/drawgraph.py +++ b/dotviewer/drawgraph.py @@ -22,6 +22,7 @@ 'yellow': (255,255,0), } re_nonword=re.compile(r'([^0-9a-zA-Z_.]+)') +re_linewidth=re.compile(r'setlinewidth\((\d+(\.\d*)?|\.\d+)\)') def combine(color1, color2, alpha): r1, g1, b1 = color1 @@ -138,6 +139,13 @@ self.yl = float(yl) rest = rest[3:] self.style, self.color = rest + linematch = re_linewidth.match(self.style) + if linematch: + num = linematch.group(1) + self.linewidth = int(round(float(num))) + self.style = self.style[linematch.end(0):] + else: + self.linewidth = 1 self.highlight = False self.cachedbezierpoints = None self.cachedarrowhead = None @@ -520,8 +528,8 @@ fgcolor = highlight_color(fgcolor) points = [self.map(*xy) for xy in edge.bezierpoints()] - def drawedgebody(points=points, fgcolor=fgcolor): - pygame.draw.lines(self.screen, fgcolor, False, points) + def drawedgebody(points=points, fgcolor=fgcolor, width=edge.linewidth): + pygame.draw.lines(self.screen, fgcolor, False, points, width) edgebodycmd.append(drawedgebody) points = [self.map(*xy) for xy in edge.arrowhead()] diff --git a/dotviewer/graphparse.py b/dotviewer/graphparse.py --- a/dotviewer/graphparse.py +++ b/dotviewer/graphparse.py @@ -152,7 +152,8 @@ try: plaincontent = dot2plain_graphviz(content, contenttype) except PlainParseError, e: - print e - # failed, retry via codespeak - plaincontent = dot2plain_codespeak(content, contenttype) + raise + ##print e + ### failed, retry via codespeak + ##plaincontent = dot2plain_codespeak(content, contenttype) return list(parse_plain(graph_id, plaincontent, links, fixedfont)) diff --git a/dotviewer/test/test_interactive.py b/dotviewer/test/test_interactive.py --- a/dotviewer/test/test_interactive.py +++ b/dotviewer/test/test_interactive.py @@ -34,6 +34,23 @@ } ''' +SOURCE2=r'''digraph f { + a; d; e; f; g; h; i; j; k; l; + a -> d [penwidth=1, style="setlinewidth(1)"]; + d -> e [penwidth=2, style="setlinewidth(2)"]; + e -> f [penwidth=4, style="setlinewidth(4)"]; + f -> g [penwidth=8, style="setlinewidth(8)"]; + g -> h [penwidth=16, style="setlinewidth(16)"]; + h -> i [penwidth=32, style="setlinewidth(32)"]; + i -> j [penwidth=64, style="setlinewidth(64)"]; + j -> k [penwidth=128, style="setlinewidth(128)"]; + k -> l [penwidth=256, style="setlinewidth(256)"]; +}''' + + + + + def setup_module(mod): if not option.pygame: py.test.skip("--pygame not enabled") @@ -161,3 +178,10 @@ page = MyPage(str(dotfile)) page.fixedfont = True graphclient.display_page(page) + +def test_linewidth(): + udir.join("graph2.dot").write(SOURCE2) + from dotviewer import graphpage, graphclient + dotfile = udir.join('graph2.dot') + page = graphpage.DotFileGraphPage(str(dotfile)) + graphclient.display_page(page) diff --git a/lib-python/2.7/distutils/sysconfig_pypy.py b/lib-python/2.7/distutils/sysconfig_pypy.py --- a/lib-python/2.7/distutils/sysconfig_pypy.py +++ b/lib-python/2.7/distutils/sysconfig_pypy.py @@ -12,6 +12,7 @@ import sys import os +import shlex from distutils.errors import DistutilsPlatformError @@ -124,11 +125,19 @@ if compiler.compiler_type == "unix": compiler.compiler_so.extend(['-O2', '-fPIC', '-Wimplicit']) compiler.shared_lib_extension = get_config_var('SO') + if "CPPFLAGS" in os.environ: + cppflags = shlex.split(os.environ["CPPFLAGS"]) + compiler.compiler.extend(cppflags) + compiler.compiler_so.extend(cppflags) + compiler.linker_so.extend(cppflags) if "CFLAGS" in os.environ: - cflags = os.environ["CFLAGS"].split() + cflags = shlex.split(os.environ["CFLAGS"]) compiler.compiler.extend(cflags) compiler.compiler_so.extend(cflags) compiler.linker_so.extend(cflags) + if "LDFLAGS" in os.environ: + ldflags = shlex.split(os.environ["LDFLAGS"]) + compiler.linker_so.extend(ldflags) from sysconfig_cpython import ( diff --git a/lib-python/2.7/json/__init__.py b/lib-python/2.7/json/__init__.py --- a/lib-python/2.7/json/__init__.py +++ b/lib-python/2.7/json/__init__.py @@ -105,6 +105,12 @@ __author__ = 'Bob Ippolito ' +try: + # PyPy speedup, the interface is different than CPython's _json + import _pypyjson +except ImportError: + _pypyjson = None + from .decoder import JSONDecoder from .encoder import JSONEncoder @@ -241,7 +247,6 @@ _default_decoder = JSONDecoder(encoding=None, object_hook=None, object_pairs_hook=None) - def load(fp, encoding=None, cls=None, object_hook=None, parse_float=None, parse_int=None, parse_constant=None, object_pairs_hook=None, **kw): """Deserialize ``fp`` (a ``.read()``-supporting file-like object containing @@ -323,7 +328,10 @@ if (cls is None and encoding is None and object_hook is None and parse_int is None and parse_float is None and parse_constant is None and object_pairs_hook is None and not kw): - return _default_decoder.decode(s) + if _pypyjson and not isinstance(s, unicode): + return _pypyjson.loads(s) + else: + return _default_decoder.decode(s) if cls is None: cls = JSONDecoder if object_hook is not None: diff --git a/lib-python/2.7/socket.py b/lib-python/2.7/socket.py --- a/lib-python/2.7/socket.py +++ b/lib-python/2.7/socket.py @@ -165,6 +165,8 @@ # All _delegate_methods must also be initialized here. send = recv = recv_into = sendto = recvfrom = recvfrom_into = _dummy __getattr__ = _dummy + def _drop(self): + pass # Wrapper around platform socket objects. This implements # a platform-independent dup() functionality. The @@ -179,12 +181,21 @@ def __init__(self, family=AF_INET, type=SOCK_STREAM, proto=0, _sock=None): if _sock is None: _sock = _realsocket(family, type, proto) - elif _type(_sock) is _realsocket: + else: + # PyPy note about refcounting: implemented with _reuse()/_drop() + # on the class '_socket.socket'. Python 3 did it differently + # with a reference counter on this class 'socket._socketobject' + # instead, but it is a less compatible change. + + # Note that a few libraries (like eventlet) poke at the + # private implementation of socket.py, passing custom + # objects to _socketobject(). These libraries need the + # following fix for use on PyPy: the custom objects need + # methods _reuse() and _drop() that maintains an explicit + # reference counter, starting at 0. When it drops back to + # zero, close() must be called. _sock._reuse() - # PyPy note about refcounting: implemented with _reuse()/_drop() - # on the class '_socket.socket'. Python 3 did it differently - # with a reference counter on this class 'socket._socketobject' - # instead, but it is a less compatible change (breaks eventlet). + self._sock = _sock def send(self, data, flags=0): @@ -216,9 +227,8 @@ def close(self): s = self._sock - if type(s) is _realsocket: - s._drop() self._sock = _closedsocket() + s._drop() close.__doc__ = _realsocket.close.__doc__ def accept(self): @@ -280,8 +290,14 @@ "_close"] def __init__(self, sock, mode='rb', bufsize=-1, close=False): - if type(sock) is _realsocket: - sock._reuse() + # Note that a few libraries (like eventlet) poke at the + # private implementation of socket.py, passing custom + # objects to _fileobject(). These libraries need the + # following fix for use on PyPy: the custom objects need + # methods _reuse() and _drop() that maintains an explicit + # reference counter, starting at 0. When it drops back to + # zero, close() must be called. + sock._reuse() self._sock = sock self.mode = mode # Not actually used in this version if bufsize < 0: @@ -317,11 +333,11 @@ self.flush() finally: s = self._sock - if type(s) is _realsocket: + self._sock = None + if s is not None: s._drop() - if self._close: - self._sock.close() - self._sock = None + if self._close: + s.close() def __del__(self): try: diff --git a/lib-python/2.7/ssl.py b/lib-python/2.7/ssl.py --- a/lib-python/2.7/ssl.py +++ b/lib-python/2.7/ssl.py @@ -110,6 +110,12 @@ suppress_ragged_eofs=True, ciphers=None): socket.__init__(self, _sock=sock._sock) + # "close" the original socket: it is not usable any more. + # this only calls _drop(), which should not actually call + # the operating system's close() because the reference + # counter is greater than 1 (we hold one too). + sock.close() + if ciphers is None and ssl_version != _SSLv2_IF_EXISTS: ciphers = _DEFAULT_CIPHERS @@ -352,11 +358,19 @@ works with the SSL connection. Just use the code from the socket module.""" - self._makefile_refs += 1 # close=True so as to decrement the reference count when done with # the file-like object. return _fileobject(self, mode, bufsize, close=True) + def _reuse(self): + self._makefile_refs += 1 + + def _drop(self): + if self._makefile_refs < 1: + self.close() + else: + self._makefile_refs -= 1 + def wrap_socket(sock, keyfile=None, certfile=None, diff --git a/lib-python/2.7/test/test_os.py b/lib-python/2.7/test/test_os.py --- a/lib-python/2.7/test/test_os.py +++ b/lib-python/2.7/test/test_os.py @@ -275,7 +275,7 @@ try: result.f_bfree = 1 self.fail("No exception thrown") - except TypeError: + except (TypeError, AttributeError): pass try: diff --git a/lib-python/2.7/test/test_socket.py b/lib-python/2.7/test/test_socket.py --- a/lib-python/2.7/test/test_socket.py +++ b/lib-python/2.7/test/test_socket.py @@ -1066,6 +1066,9 @@ def recv(self, size): return self._recv_step.next()() + def _reuse(self): pass + def _drop(self): pass + @staticmethod def _raise_eintr(): raise socket.error(errno.EINTR) @@ -1321,7 +1324,8 @@ closed = False def flush(self): pass def close(self): self.closed = True - def _decref_socketios(self): pass + def _reuse(self): pass + def _drop(self): pass # must not close unless we request it: the original use of _fileobject # by module socket requires that the underlying socket not be closed until diff --git a/lib-python/2.7/test/test_urllib2.py b/lib-python/2.7/test/test_urllib2.py --- a/lib-python/2.7/test/test_urllib2.py +++ b/lib-python/2.7/test/test_urllib2.py @@ -270,6 +270,8 @@ self.reason = reason def read(self): return '' + def _reuse(self): pass + def _drop(self): pass class MockHTTPClass: def __init__(self): diff --git a/lib-python/2.7/urllib2.py b/lib-python/2.7/urllib2.py --- a/lib-python/2.7/urllib2.py +++ b/lib-python/2.7/urllib2.py @@ -1193,6 +1193,8 @@ # out of socket._fileobject() and into a base class. r.recv = r.read + r._reuse = lambda: None + r._drop = lambda: None fp = socket._fileobject(r, close=True) resp = addinfourl(fp, r.msg, req.get_full_url()) diff --git a/lib-python/2.7/uuid.py b/lib-python/2.7/uuid.py --- a/lib-python/2.7/uuid.py +++ b/lib-python/2.7/uuid.py @@ -44,6 +44,8 @@ UUID('00010203-0405-0607-0809-0a0b0c0d0e0f') """ +import struct + __author__ = 'Ka-Ping Yee ' RESERVED_NCS, RFC_4122, RESERVED_MICROSOFT, RESERVED_FUTURE = [ @@ -125,25 +127,38 @@ overriding the given 'hex', 'bytes', 'bytes_le', 'fields', or 'int'. """ - if [hex, bytes, bytes_le, fields, int].count(None) != 4: - raise TypeError('need one of hex, bytes, bytes_le, fields, or int') if hex is not None: + if (bytes is not None or bytes_le is not None or fields is not None + or int is not None): + raise TypeError('if the hex argument is given, bytes, bytes_le, fields,' + ' and int need to be None') hex = hex.replace('urn:', '').replace('uuid:', '') hex = hex.strip('{}').replace('-', '') if len(hex) != 32: raise ValueError('badly formed hexadecimal UUID string') int = long(hex, 16) - if bytes_le is not None: + elif bytes_le is not None: + if bytes is not None or fields is not None or int is not None: + raise TypeError('if the bytes_le argument is given, bytes, fields,' + ' and int need to be None') if len(bytes_le) != 16: raise ValueError('bytes_le is not a 16-char string') bytes = (bytes_le[3] + bytes_le[2] + bytes_le[1] + bytes_le[0] + bytes_le[5] + bytes_le[4] + bytes_le[7] + bytes_le[6] + bytes_le[8:]) - if bytes is not None: + int = (struct.unpack('>Q', bytes[:8])[0] << 64 | + struct.unpack('>Q', bytes[8:])[0]) + elif bytes is not None: + if fields is not None or int is not None: + raise TypeError('if the bytes argument is given, fields' + ' and int need to be None') if len(bytes) != 16: raise ValueError('bytes is not a 16-char string') - int = long(('%02x'*16) % tuple(map(ord, bytes)), 16) - if fields is not None: + int = (struct.unpack('>Q', bytes[:8])[0] << 64 | + struct.unpack('>Q', bytes[8:])[0]) + elif fields is not None: + if int is not None: + raise TypeError('if the fields argument is given, int needs to be None') if len(fields) != 6: raise ValueError('fields is not a 6-tuple') (time_low, time_mid, time_hi_version, @@ -163,9 +178,12 @@ clock_seq = (clock_seq_hi_variant << 8L) | clock_seq_low int = ((time_low << 96L) | (time_mid << 80L) | (time_hi_version << 64L) | (clock_seq << 48L) | node) - if int is not None: + elif int is not None: if not 0 <= int < 1<<128L: raise ValueError('int is out of range (need a 128-bit value)') + else: + raise TypeError('one of hex, bytes, bytes_le, fields,' + ' or int need to be not None') if version is not None: if not 1 <= version <= 5: raise ValueError('illegal version number') @@ -175,7 +193,7 @@ # Set the version number. int &= ~(0xf000 << 64L) int |= version << 76L - self.__dict__['int'] = int + object.__setattr__(self, 'int', int) def __cmp__(self, other): if isinstance(other, UUID): diff --git a/lib_pypy/_curses.py b/lib_pypy/_curses.py --- a/lib_pypy/_curses.py +++ b/lib_pypy/_curses.py @@ -1,6 +1,9 @@ """Reimplementation of the standard extension module '_curses' using cffi.""" import sys +if sys.platform == 'win32': + #This module does not exist in windows + raise ImportError('No module named _curses') from functools import wraps from cffi import FFI @@ -966,7 +969,7 @@ r, g, b = ffi.new("short *"), ffi.new("short *"), ffi.new("short *") if lib.color_content(color, r, g, b) == lib.ERR: raise error("Argument 1 was out of range. Check value of COLORS.") - return (r, g, b) + return (r[0], g[0], b[0]) def color_pair(n): @@ -1121,6 +1124,7 @@ term = ffi.NULL err = ffi.new("int *") if lib.setupterm(term, fd, err) == lib.ERR: + err = err[0] if err == 0: raise error("setupterm: could not find terminal") elif err == -1: diff --git a/lib_pypy/_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 @@ -165,6 +165,63 @@ Nyy rkprcgoybpxf frrz fnar. N cvax tyvggrel ebgngvat ynzoqn "vg'f yvxryl grzcbenel hagvy sberire" nevtb +"Lbh xabj jung'f avpr nobhg EClguba? Ybatre fjbeq svtugf." +nccneragyl pbashfvba vf n srngher +nccneragyl pbashfvba vf n srngher... be vf vg? +ClCl 1.7 eryrnfrq +vs lbh jnag gb or penml, lbh qba'g unir gb sbepr vg +vs lbh jnag vg gb or iveghny, lbh fubhyq abg sbepr vg + svwny: V whfg... fgnegrq pbqvat naq fhqqragyl... nobzvangvba +fabj, fabj! :-) +fabj, fabj, fabj, fabj +clcl 1.8 eryrnfrq +vg jnf srj lnxf gbb yngr +ClCl vf n enpr orgjrra hf funivat lnxf, naq gur havirefr gelvat gb cebqhpr zber naq zber lnxf +Jevgvat na SC7 nabalzbhf cebcbfny sbe ClCl vf yvxr znxvat n gi nq sbe n uvtu cresbeznapr fcbegf pne jvgubhg orvat noyr gb zragvba vgf zbqry be znahsnpghere +Fabj, fabj (ntnva) +Fgvyy fabjvat +thrff jung, fabj +"lbh haqrerfgvzngr gur vzcbegnapr bs zvpebnepuvgrpgher" "ab, vg'f zber gung jr ner fgvyy unccvyl va gur ynaq bs ernpunoyr sehvg" +Jub nz V? Naq vs lrf, ubj znal? +ClCl vf nyjnlf n cynfzn +"genafyngvba gbbypunva" = "EClgure"? gb jevgr vagrEClguref va +"sberire" va clcl grezf zrnaf yvxr srj zbaguf :) +"Onu. PClguba bofphevgl. - Nezva Evtb" +svwny: pna V vavgvngr lbh ba gur (rnfl ohg) aba-gevivny gbcvp bs jevgvat P shapgvba glcrf? :-) +nyy fbsgjner vzcebirzragf unccra ol n ovg +gur genprf qba'g yvr +:-) be engure ":-/" bss-ol-bar-xrl reebe +Be Nezva Evtb. V guvax ur'f noyr gb haqrefgnaq k86 gur jnl Plcure pna frr jbzra va gur zngevk. +V zvtug, ohg abobql erfcrpgf zr +cerohvyg vafgnapr Ryyvcfvf unf ab nggevohgr 'reeab' +guvf frnfba'f svefg "fabj! fabj!" vf urer +ClCl 2.0 orgn1 eryrnfrq - orggre yngr guna arire +Fjvgreynaq 2012: zber fabj va Qrprzore guna rire fvapr clcl fgnegrq +Fjvgmreynaq 2012: zber fabj va Qrprzore guna rire fvapr clcl fgnegrq + n sngny reebe, ol qrsvavgvba, vf sngny + V'z tynq gung jr cebtenz va Clguba naq jr qba'g qrny jvgu gubfr vffhrf rirel qnl. Ncneg gur snpg gung jr unir gb qrny jvgu gurz naljnl, vg frrzf +unccl arj lrne! +"zrffl" vf abg n whqtrzrag, ohg whfg n snpg bs pbzcyvpngrqarff +n ybg bs fabj +qb lbh xabj nobhg n gbnfgre jvgu 8XO bs ENZ naq 64XO bs EBZ? +vg'f orra fabjvat rirelqnl sbe n juvyr, V pna'g whfg chg "fabj, fabj" hc urer rirel qnl +fabjonyy svtugf! +sbejneq pbzcngvovyvgl jvgu bcgvzvmngvbaf gung unira'g orra vairagrq lrg +jr fgvyy unir gb jevgr fbsgjner jvgu n zrgnfcnpr ohooyr va vg +cebonoyl gur ynfg gvzr va gur frnfba, ohg: fabj, fabj! +ClCl 2.0-orgn2 eryrnfrq +Gur ceboyrz vf gung sbe nyzbfg nal aba-gevivny cebtenz, vg'f abg pyrne jung 'pbeerpg' zrnaf. +ClCl 2.0 nyzbfg eryrnfrq +ClCl 2.0 eryrnfrq +WVG pbzcvyref fubhyq or jevggra ol crbcyr jub npghnyyl unir snvgu va WVG pbzcvyref' novyvgl gb znxrf guvatf tb fpernzvat snfg +ClCl 2.0.1 eryrnfrq +arire haqrerfgvzngr gur vzcebonoyr jura lbh qb fbzrguvat ng 2TUm +ClCl 2.0.2 eryrnfrq +nyy jr arrq vf n angvir Cebybt znpuvar +V haqrefgnaq ubj qravnyvfz vf n onq qrohttvat grpuavdhr +rirel IZ fubhyq pbzr jvgu arheny argjbex genvarq gb erpbtavmr zvpeborapuznexf naq enaqbzyl syhpghngr gurz +/-9000% +lbh qvq abg nccebnpu clcl sebz gur rnfl raq: fgz, gura wvg. vg'f n ovg gur Abegu snpr +va ClCl orvat bayl zbqrengryl zntvp vf n tbbq guvat """ from string import ascii_uppercase, ascii_lowercase diff --git a/lib_pypy/_sqlite3.py b/lib_pypy/_sqlite3.py --- a/lib_pypy/_sqlite3.py +++ b/lib_pypy/_sqlite3.py @@ -1229,7 +1229,10 @@ if cvt is not None: param = cvt(param) - param = adapt(param) + try: + param = adapt(param) + except: + pass # And use previous value if param is None: rc = _lib.sqlite3_bind_null(self._statement, idx) @@ -1305,7 +1308,7 @@ for i in xrange(_lib.sqlite3_column_count(self._statement)): name = _lib.sqlite3_column_name(self._statement, i) if name: - name = _ffi.string(name).decode('utf-8').split("[")[0].strip() + name = _ffi.string(name).split("[")[0].strip() desc.append((name, None, None, None, None, None, None)) return desc diff --git a/lib_pypy/cffi.egg-info b/lib_pypy/cffi.egg-info --- a/lib_pypy/cffi.egg-info +++ b/lib_pypy/cffi.egg-info @@ -1,6 +1,6 @@ Metadata-Version: 1.0 Name: cffi -Version: 0.6 +Version: 0.7 Summary: Foreign Function Interface for Python calling C code. Home-page: http://cffi.readthedocs.org Author: Armin Rigo, Maciej Fijalkowski diff --git a/lib_pypy/cffi/__init__.py b/lib_pypy/cffi/__init__.py --- a/lib_pypy/cffi/__init__.py +++ b/lib_pypy/cffi/__init__.py @@ -4,5 +4,5 @@ from .api import FFI, CDefError, FFIError from .ffiplatform import VerificationError, VerificationMissing -__version__ = "0.7" -__version_info__ = (0, 7) +__version__ = "0.7.2" +__version_info__ = (0, 7, 2) diff --git a/lib_pypy/cffi/api.py b/lib_pypy/cffi/api.py --- a/lib_pypy/cffi/api.py +++ b/lib_pypy/cffi/api.py @@ -54,7 +54,8 @@ # _cffi_backend.so compiled. import _cffi_backend as backend from . import __version__ - assert backend.__version__ == __version__ + assert (backend.__version__ == __version__ or + backend.__version__ == __version__[:3]) # (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.) diff --git a/lib_pypy/cffi/commontypes.py b/lib_pypy/cffi/commontypes.py --- a/lib_pypy/cffi/commontypes.py +++ b/lib_pypy/cffi/commontypes.py @@ -30,7 +30,9 @@ elif result in model.PrimitiveType.ALL_PRIMITIVE_TYPES: result = model.PrimitiveType(result) else: - assert commontype != result + if commontype == result: + raise api.FFIError("Unsupported type: %r. Please file a bug " + "if you think it should be." % (commontype,)) result = resolve_common_type(result) # recursively assert isinstance(result, model.BaseTypeByIdentity) _CACHE[commontype] = result diff --git a/lib_pypy/cffi/cparser.py b/lib_pypy/cffi/cparser.py --- a/lib_pypy/cffi/cparser.py +++ b/lib_pypy/cffi/cparser.py @@ -290,13 +290,26 @@ # assume a primitive type. get it from .names, but reduce # synonyms to a single chosen combination names = list(type.names) - if names == ['signed'] or names == ['unsigned']: - names.append('int') - if names[0] == 'signed' and names != ['signed', 'char']: - names.pop(0) - if (len(names) > 1 and names[-1] == 'int' - and names != ['unsigned', 'int']): - names.pop() + if names != ['signed', 'char']: # keep this unmodified + prefixes = {} + while names: + name = names[0] + if name in ('short', 'long', 'signed', 'unsigned'): + prefixes[name] = prefixes.get(name, 0) + 1 + del names[0] + else: + break + # ignore the 'signed' prefix below, and reorder the others + newnames = [] + for prefix in ('unsigned', 'short', 'long'): + for i in range(prefixes.get(prefix, 0)): + newnames.append(prefix) + if not names: + names = ['int'] # implicitly + if names == ['int']: # but kill it if 'short' or 'long' + if 'short' in prefixes or 'long' in prefixes: + names = [] + names = newnames + names ident = ' '.join(names) if ident == 'void': return model.void_type @@ -500,8 +513,8 @@ self._partial_length = True return None # - raise api.FFIError("unsupported non-constant or " - "not immediately constant expression") + raise api.FFIError("unsupported expression: expected a " + "simple numeric constant") def _build_enum_type(self, explicit_name, decls): if decls is not None: diff --git a/lib_pypy/cffi/vengine_gen.py b/lib_pypy/cffi/vengine_gen.py --- a/lib_pypy/cffi/vengine_gen.py +++ b/lib_pypy/cffi/vengine_gen.py @@ -61,7 +61,9 @@ def load_library(self): # import it with the CFFI backend backend = self.ffi._backend - module = backend.load_library(self.verifier.modulefilename) + # needs to make a path that contains '/', on Posix + filename = os.path.join(os.curdir, self.verifier.modulefilename) + module = backend.load_library(filename) # # call loading_gen_struct() to get the struct layout inferred by # the C compiler diff --git a/lib_pypy/ctypes_config_cache/syslog.ctc.py b/lib_pypy/ctypes_config_cache/syslog.ctc.py deleted file mode 100644 --- a/lib_pypy/ctypes_config_cache/syslog.ctc.py +++ /dev/null @@ -1,75 +0,0 @@ -""" -'ctypes_configure' source for syslog.py. -Run this to rebuild _syslog_cache.py. -""" - -from ctypes_configure.configure import (configure, - ExternalCompilationInfo, ConstantInteger, DefinedConstantInteger) -import dumpcache - - -_CONSTANTS = ( - 'LOG_EMERG', - 'LOG_ALERT', - 'LOG_CRIT', - 'LOG_ERR', - 'LOG_WARNING', - 'LOG_NOTICE', - 'LOG_INFO', - 'LOG_DEBUG', - - 'LOG_PID', - 'LOG_CONS', - 'LOG_NDELAY', - - 'LOG_KERN', - 'LOG_USER', - 'LOG_MAIL', - 'LOG_DAEMON', - 'LOG_AUTH', - 'LOG_LPR', - 'LOG_LOCAL0', - 'LOG_LOCAL1', - 'LOG_LOCAL2', - 'LOG_LOCAL3', - 'LOG_LOCAL4', - 'LOG_LOCAL5', - 'LOG_LOCAL6', - 'LOG_LOCAL7', -) -_OPTIONAL_CONSTANTS = ( - 'LOG_NOWAIT', - 'LOG_PERROR', - - 'LOG_SYSLOG', - 'LOG_CRON', - 'LOG_UUCP', - 'LOG_NEWS', -) - -# Constant aliases if there are not defined -_ALIAS = ( - ('LOG_SYSLOG', 'LOG_DAEMON'), - ('LOG_CRON', 'LOG_DAEMON'), - ('LOG_NEWS', 'LOG_MAIL'), - ('LOG_UUCP', 'LOG_MAIL'), -) - -class SyslogConfigure: - _compilation_info_ = ExternalCompilationInfo(includes=['sys/syslog.h']) -for key in _CONSTANTS: - setattr(SyslogConfigure, key, ConstantInteger(key)) -for key in _OPTIONAL_CONSTANTS: - setattr(SyslogConfigure, key, DefinedConstantInteger(key)) - -config = configure(SyslogConfigure) -for key in _OPTIONAL_CONSTANTS: - if config[key] is None: - del config[key] -for alias, key in _ALIAS: - config.setdefault(alias, config[key]) - -all_constants = config.keys() -all_constants.sort() -config['ALL_CONSTANTS'] = tuple(all_constants) -dumpcache.dumpcache2('syslog', config) diff --git a/lib_pypy/datetime.py b/lib_pypy/datetime.py --- a/lib_pypy/datetime.py +++ b/lib_pypy/datetime.py @@ -40,9 +40,9 @@ # for all computations. See the book for algorithms for converting between # proleptic Gregorian ordinals and many other calendar systems. -_DAYS_IN_MONTH = [None, 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31] +_DAYS_IN_MONTH = [-1, 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31] -_DAYS_BEFORE_MONTH = [None] +_DAYS_BEFORE_MONTH = [-1] dbm = 0 for dim in _DAYS_IN_MONTH[1:]: _DAYS_BEFORE_MONTH.append(dbm) diff --git a/lib_pypy/greenlet.py b/lib_pypy/greenlet.py --- a/lib_pypy/greenlet.py +++ b/lib_pypy/greenlet.py @@ -1,3 +1,4 @@ +import sys import _continuation __version__ = "0.4.0" @@ -5,7 +6,7 @@ # ____________________________________________________________ # Exceptions -class GreenletExit(Exception): +class GreenletExit(BaseException): """This special exception does not propagate to the parent greenlet; it can be used to kill a single greenlet.""" @@ -46,16 +47,16 @@ if parent is not None: self.parent = parent - def switch(self, *args): + def switch(self, *args, **kwds): "Switch execution to this greenlet, optionally passing the values " "given as argument(s). Returns the value passed when switching back." - return self.__switch('switch', args) + return self.__switch('switch', (args, kwds)) def throw(self, typ=GreenletExit, val=None, tb=None): "raise exception in greenlet, return value passed when switching back" return self.__switch('throw', typ, val, tb) - def __switch(target, methodname, *args): + def __switch(target, methodname, *baseargs): current = getcurrent() # while not (target.__main or _continulet.is_pending(target)): @@ -65,9 +66,9 @@ greenlet_func = _greenlet_start else: greenlet_func = _greenlet_throw - _continulet.__init__(target, greenlet_func, *args) + _continulet.__init__(target, greenlet_func, *baseargs) methodname = 'switch' - args = () + baseargs = () target.__started = True break # already done, go to the parent instead @@ -75,14 +76,27 @@ # up the 'parent' explicitly. Good enough, because a Ctrl-C # will show that the program is caught in this loop here.) target = target.parent + # convert a "raise GreenletExit" into "return GreenletExit" + if methodname == 'throw': + try: + raise baseargs[0], baseargs[1] + except GreenletExit, e: + methodname = 'switch' + baseargs = (((e,), {}),) + except: + baseargs = sys.exc_info()[:2] + baseargs[2:] # try: unbound_method = getattr(_continulet, methodname) - args = unbound_method(current, *args, to=target) + args, kwds = unbound_method(current, *baseargs, to=target) finally: _tls.current = current # - if len(args) == 1: + if kwds: + if args: + return args, kwds + return kwds + elif len(args) == 1: return args[0] else: return args @@ -129,18 +143,22 @@ _tls.current = gmain def _greenlet_start(greenlet, args): + args, kwds = args _tls.current = greenlet try: - res = greenlet.run(*args) + res = greenlet.run(*args, **kwds) except GreenletExit, e: res = e finally: _continuation.permute(greenlet, greenlet.parent) - return (res,) + return ((res,), None) def _greenlet_throw(greenlet, exc, value, tb): _tls.current = greenlet try: raise exc, value, tb + except GreenletExit, e: + res = e finally: _continuation.permute(greenlet, greenlet.parent) + return ((res,), None) diff --git a/lib_pypy/grp.py b/lib_pypy/grp.py --- a/lib_pypy/grp.py +++ b/lib_pypy/grp.py @@ -8,6 +8,7 @@ from ctypes import Structure, c_char_p, c_int, POINTER from ctypes_support import standard_c_lib as libc +import _structseq try: from __pypy__ import builtinify except ImportError: builtinify = lambda f: f @@ -23,32 +24,13 @@ ('gr_mem', POINTER(c_char_p)), ) -class Group(object): - def __init__(self, gr_name, gr_passwd, gr_gid, gr_mem): - self.gr_name = gr_name - self.gr_passwd = gr_passwd - self.gr_gid = gr_gid - self.gr_mem = gr_mem +class struct_group: + __metaclass__ = _structseq.structseqtype - def __getitem__(self, item): - if item == 0: - return self.gr_name - elif item == 1: - return self.gr_passwd - elif item == 2: - return self.gr_gid - elif item == 3: - return self.gr_mem - else: - raise IndexError(item) - - def __len__(self): - return 4 - - def __repr__(self): - return str((self.gr_name, self.gr_passwd, self.gr_gid, self.gr_mem)) - - # whatever else... + gr_name = _structseq.structseqfield(0) + gr_passwd = _structseq.structseqfield(1) + gr_gid = _structseq.structseqfield(2) + gr_mem = _structseq.structseqfield(3) libc.getgrgid.argtypes = [gid_t] libc.getgrgid.restype = POINTER(GroupStruct) @@ -71,8 +53,8 @@ while res.contents.gr_mem[i]: mem.append(res.contents.gr_mem[i]) i += 1 - return Group(res.contents.gr_name, res.contents.gr_passwd, - res.contents.gr_gid, mem) + return struct_group((res.contents.gr_name, res.contents.gr_passwd, + res.contents.gr_gid, mem)) @builtinify def getgrgid(gid): diff --git a/lib_pypy/pyrepl/curses.py b/lib_pypy/pyrepl/curses.py --- a/lib_pypy/pyrepl/curses.py +++ b/lib_pypy/pyrepl/curses.py @@ -19,11 +19,15 @@ # CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN # CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. -# avoid importing the whole curses, if possible -try: +# If we are running on top of pypy, we import only _minimal_curses. +# Don't try to fall back to _curses, because that's going to use cffi +# and fall again more loudly. +import sys +if '__pypy__' in sys.builtin_module_names: # pypy case import _minimal_curses as _curses -except ImportError: +else: + # cpython case try: import _curses except ImportError: diff --git a/lib_pypy/readline.egg-info b/lib_pypy/readline.egg-info new file mode 100644 --- /dev/null +++ b/lib_pypy/readline.egg-info @@ -0,0 +1,10 @@ +Metadata-Version: 1.0 +Name: readline +Version: 6.2.4.1 +Summary: Hack to make "pip install readline" happy and do nothing +Home-page: UNKNOWN +Author: UNKNOWN +Author-email: UNKNOWN +License: UNKNOWN +Description: UNKNOWN +Platform: UNKNOWN diff --git a/lib_pypy/syslog.py b/lib_pypy/syslog.py --- a/lib_pypy/syslog.py +++ b/lib_pypy/syslog.py @@ -1,3 +1,4 @@ +# this cffi version was rewritten based on the # ctypes implementation: Victor Stinner, 2008-05-08 """ This module provides an interface to the Unix syslog library routines. @@ -9,34 +10,84 @@ if sys.platform == 'win32': raise ImportError("No syslog on Windows") -# load the platform-specific cache made by running syslog.ctc.py -from ctypes_config_cache._syslog_cache import * - -from ctypes_support import standard_c_lib as libc -from ctypes import c_int, c_char_p +from cffi import FFI try: from __pypy__ import builtinify except ImportError: builtinify = lambda f: f +ffi = FFI() -# Real prototype is: -# void syslog(int priority, const char *format, ...); -# But we also need format ("%s") and one format argument (message) -_syslog = libc.syslog -_syslog.argtypes = (c_int, c_char_p, c_char_p) -_syslog.restype = None +ffi.cdef(""" +/* mandatory constants */ +#define LOG_EMERG ... +#define LOG_ALERT ... +#define LOG_CRIT ... +#define LOG_ERR ... +#define LOG_WARNING ... +#define LOG_NOTICE ... +#define LOG_INFO ... +#define LOG_DEBUG ... -_openlog = libc.openlog -_openlog.argtypes = (c_char_p, c_int, c_int) -_openlog.restype = None +#define LOG_PID ... +#define LOG_CONS ... +#define LOG_NDELAY ... -_closelog = libc.closelog -_closelog.argtypes = None -_closelog.restype = None +#define LOG_KERN ... +#define LOG_USER ... +#define LOG_MAIL ... +#define LOG_DAEMON ... +#define LOG_AUTH ... +#define LOG_LPR ... +#define LOG_LOCAL0 ... +#define LOG_LOCAL1 ... +#define LOG_LOCAL2 ... +#define LOG_LOCAL3 ... +#define LOG_LOCAL4 ... +#define LOG_LOCAL5 ... +#define LOG_LOCAL6 ... +#define LOG_LOCAL7 ... -_setlogmask = libc.setlogmask -_setlogmask.argtypes = (c_int,) -_setlogmask.restype = c_int +/* optional constants, gets defined to -919919 if missing */ +#define LOG_NOWAIT ... +#define LOG_PERROR ... + +/* aliased constants, gets defined as some other constant if missing */ +#define LOG_SYSLOG ... +#define LOG_CRON ... +#define LOG_UUCP ... +#define LOG_NEWS ... + +/* functions */ +void openlog(const char *ident, int option, int facility); +void syslog(int priority, const char *format, const char *string); +// NB. the signature of syslog() is specialized to the only case we use +void closelog(void); +int setlogmask(int mask); +""") + +lib = ffi.verify(""" +#include + +#ifndef LOG_NOWAIT +#define LOG_NOWAIT -919919 +#endif +#ifndef LOG_PERROR +#define LOG_PERROR -919919 +#endif +#ifndef LOG_SYSLOG +#define LOG_SYSLOG LOG_DAEMON +#endif +#ifndef LOG_CRON +#define LOG_CRON LOG_DAEMON +#endif +#ifndef LOG_UUCP +#define LOG_UUCP LOG_MAIL +#endif +#ifndef LOG_NEWS +#define LOG_NEWS LOG_MAIL +#endif +""") + _S_log_open = False _S_ident_o = None @@ -52,12 +103,17 @@ return None @builtinify -def openlog(ident=None, logoption=0, facility=LOG_USER): +def openlog(ident=None, logoption=0, facility=lib.LOG_USER): global _S_ident_o, _S_log_open if ident is None: ident = _get_argv() - _S_ident_o = c_char_p(ident) # keepalive - _openlog(_S_ident_o, logoption, facility) + if ident is None: + _S_ident_o = ffi.NULL + elif isinstance(ident, str): + _S_ident_o = ffi.new("char[]", ident) # keepalive + else: + raise TypeError("'ident' must be a string or None") + lib.openlog(_S_ident_o, logoption, facility) _S_log_open = True @builtinify @@ -69,19 +125,19 @@ # if log is not opened, open it now if not _S_log_open: openlog() - _syslog(priority, "%s", message) + lib.syslog(priority, "%s", message) @builtinify def closelog(): global _S_log_open, S_ident_o if _S_log_open: - _closelog() + lib.closelog() _S_log_open = False _S_ident_o = None @builtinify def setlogmask(mask): - return _setlogmask(mask) + return lib.setlogmask(mask) @builtinify def LOG_MASK(pri): @@ -91,8 +147,15 @@ def LOG_UPTO(pri): return (1 << (pri + 1)) - 1 -__all__ = ALL_CONSTANTS + ( +__all__ = [] + +for name in sorted(lib.__dict__): + if name.startswith('LOG_'): + value = getattr(lib, name) + if value != -919919: + globals()[name] = value + __all__.append(name) + +__all__ = tuple(__all__) + ( 'openlog', 'syslog', 'closelog', 'setlogmask', 'LOG_MASK', 'LOG_UPTO') - -del ALL_CONSTANTS diff --git a/pypy/config/pypyoption.py b/pypy/config/pypyoption.py --- a/pypy/config/pypyoption.py +++ b/pypy/config/pypyoption.py @@ -35,7 +35,7 @@ "thread", "itertools", "pyexpat", "_ssl", "cpyext", "array", "binascii", "_multiprocessing", '_warnings', "_collections", "_multibytecodec", "micronumpy", "_ffi", - "_continuation", "_cffi_backend", "_csv", "cppyy"] + "_continuation", "_cffi_backend", "_csv", "cppyy", "_pypyjson"] )) translation_modules = default_modules.copy() @@ -48,11 +48,6 @@ "termios", "_minimal_curses", ])) -working_oo_modules = default_modules.copy() -working_oo_modules.update(dict.fromkeys( - ["_md5", "_sha", "cStringIO", "itertools"] -)) - # XXX this should move somewhere else, maybe to platform ("is this posixish" # check or something) if sys.platform == "win32": @@ -132,11 +127,6 @@ pypy_optiondescription = OptionDescription("objspace", "Object Space Options", [ - OptionDescription("opcodes", "opcodes to enable in the interpreter", [ - BoolOption("CALL_METHOD", "emit a special bytecode for expr.name()", - default=False), - ]), - OptionDescription("usemodules", "Which Modules should be used", [ BoolOption(modname, "use module %s" % (modname, ), default=modname in default_modules, @@ -144,7 +134,7 @@ requires=module_dependencies.get(modname, []), suggests=module_suggests.get(modname, []), negation=modname not in essential_modules, - validator=get_module_validator(modname)) + ) #validator=get_module_validator(modname)) for modname in all_modules]), BoolOption("allworkingmodules", "use as many working modules as possible", @@ -264,9 +254,6 @@ BoolOption("optimized_int_add", "special case the addition of two integers in BINARY_ADD", default=False), - BoolOption("optimized_comparison_op", - "special case the comparison of integers", - default=False), BoolOption("optimized_list_getitem", "special case the 'list[integer]' expressions", default=False), @@ -312,7 +299,6 @@ # all the good optimizations for PyPy should be listed here if level in ['2', '3', 'jit']: - config.objspace.opcodes.suggest(CALL_METHOD=True) config.objspace.std.suggest(withrangelist=True) config.objspace.std.suggest(withmethodcache=True) config.objspace.std.suggest(withprebuiltchar=True) @@ -340,10 +326,6 @@ if not IS_64_BITS: config.objspace.std.suggest(withsmalllong=True) - # some optimizations have different effects depending on the typesystem - if type_system == 'ootype': - config.objspace.std.suggest(multimethods="doubledispatch") - # extra optimizations with the JIT if level == 'jit': config.objspace.std.suggest(withcelldict=True) @@ -357,10 +339,7 @@ def enable_allworkingmodules(config): - if config.translation.type_system == 'ootype': - modules = working_oo_modules - else: - modules = working_modules + modules = working_modules if config.translation.sandbox: modules = default_modules # ignore names from 'essential_modules', notably 'exceptions', which diff --git a/pypy/doc/_ref.txt b/pypy/doc/_ref.txt --- a/pypy/doc/_ref.txt +++ b/pypy/doc/_ref.txt @@ -99,8 +99,6 @@ .. _`rpython/rtyper/memory/gc/hybrid.py`: https://bitbucket.org/pypy/pypy/src/default/rpython/rtyper/memory/gc/hybrid.py .. _`rpython/rtyper/memory/gc/minimarkpage.py`: https://bitbucket.org/pypy/pypy/src/default/rpython/rtyper/memory/gc/minimarkpage.py .. _`rpython/rtyper/memory/gc/semispace.py`: https://bitbucket.org/pypy/pypy/src/default/rpython/rtyper/memory/gc/semispace.py -.. _`rpython/rtyper/ootypesystem/`: https://bitbucket.org/pypy/pypy/src/default/rpython/rtyper/ootypesystem/ -.. _`rpython/rtyper/ootypesystem/ootype.py`: https://bitbucket.org/pypy/pypy/src/default/rpython/rtyper/ootypesystem/ootype.py .. _`rpython/rtyper/rint.py`: https://bitbucket.org/pypy/pypy/src/default/rpython/rtyper/rint.py .. _`rpython/rtyper/rlist.py`: https://bitbucket.org/pypy/pypy/src/default/rpython/rtyper/rlist.py .. _`rpython/rtyper/rmodel.py`: https://bitbucket.org/pypy/pypy/src/default/rpython/rtyper/rmodel.py diff --git a/pypy/doc/cli-backend.rst b/pypy/doc/cli-backend.rst deleted file mode 100644 --- a/pypy/doc/cli-backend.rst +++ /dev/null @@ -1,455 +0,0 @@ -=============== -The CLI backend -=============== - -The goal of GenCLI is to compile RPython programs to the CLI virtual -machine. - - -Target environment and language -=============================== - -The target of GenCLI is the Common Language Infrastructure environment -as defined by the `Standard Ecma 335`_. - -While in an ideal world we might suppose GenCLI to run fine with -every implementation conforming to that standard, we know the world we -live in is far from ideal, so extra efforts can be needed to maintain -compatibility with more than one implementation. - -At the moment of writing the two most popular implementations of the -standard are supported: Microsoft Common Language Runtime (CLR) and -Mono. - -Then we have to choose how to generate the real executables. There are -two main alternatives: generating source files in some high level -language (such as C#) or generating assembly level code in -Intermediate Language (IL). - -The IL approach is much faster during the code generation -phase, because it doesn't need to call a compiler. By contrast the -high level approach has two main advantages: - - - the code generation part could be easier because the target - language supports high level control structures such as - structured loops; - - - the generated executables take advantage of compiler's - optimizations. - -In reality the first point is not an advantage in the PyPy context, -because the `flow graph`_ we start from is quite low level and Python -loops are already expressed in terms of branches (i.e., gotos). - -About the compiler optimizations we must remember that the flow graph -we receive from earlier stages is already optimized: PyPy implements -a number of optimizations such a constant propagation and -dead code removal, so it's not obvious if the compiler could -do more. - -Moreover by emitting IL instruction we are not constrained to rely on -compiler choices but can directly choose how to map CLI opcodes: since -the backend often know more than the compiler about the context, we -might expect to produce more efficient code by selecting the most -appropriate instruction; e.g., we can check for arithmetic overflow -only when strictly necessary. - -The last but not least reason for choosing the low level approach is -flexibility in how to get an executable starting from the IL code we -generate: - - - write IL code to a file, then call the ilasm assembler; - - - directly generate code on the fly by accessing the facilities - exposed by the System.Reflection.Emit API. - - -Handling platform differences -============================= - -Since our goal is to support both Microsoft CLR we have to handle the -differences between the twos; in particular the main differences are -in the name of the helper tools we need to call: - -=============== ======== ====== -Tool CLR Mono -=============== ======== ====== -IL assembler ilasm ilasm2 -C# compiler csc gmcs -Runtime ... mono -=============== ======== ====== - -The code that handles these differences is located in the sdk.py -module: it defines an abstract class which exposes some methods -returning the name of the helpers and one subclass for each of the two -supported platforms. - -Since Microsoft ``ilasm`` is not capable of compiling the PyPy -standard interpreter due to its size, on Windows machines we also look -for an existing Mono installation: if present, we use CLR for -everything except the assembling phase, for which we use Mono's -``ilasm2``. - - -Targeting the CLI Virtual Machine -================================= - -In order to write a CLI backend we have to take a number of decisions. -First, we have to choose the typesystem to use: given that CLI -natively supports primitives like classes and instances, -ootypesystem is the most natural choice. - -Once the typesystem has been chosen there is a number of steps we have -to do for completing the backend: - - - map ootypesystem's types to CLI Common Type System's - types; - - - map ootypesystem's low level operation to CLI instructions; - - - map Python exceptions to CLI exceptions; - - - write a code generator that translates a flow graph - into a list of CLI instructions; - - - write a class generator that translates ootypesystem - classes into CLI classes. - - -Mapping primitive types ------------------------ - -The `rtyper`_ give us a flow graph annotated with types belonging to -ootypesystem: in order to produce CLI code we need to translate these -types into their Common Type System equivalents. - -For numeric types the conversion is straightforward, since -there is a one-to-one mapping between the two typesystems, so that -e.g. Float maps to float64. - -For character types the choice is more difficult: RPython has two -distinct types for plain ASCII and Unicode characters (named UniChar), -while .NET only supports Unicode with the char type. There are at -least two ways to map plain Char to CTS: - - - map UniChar to char, thus maintaining the original distinction - between the two types: this has the advantage of being a - one-to-one translation, but has the disadvantage that RPython - strings will not be recognized as .NET strings, since they only - would be sequences of bytes; - - - map both char, so that Python strings will be treated as strings - also by .NET: in this case there could be problems with existing - Python modules that use strings as sequences of byte, such as the - built-in struct module, so we need to pay special attention. - -We think that mapping Python strings to .NET strings is -fundamental, so we chose the second option. - -Mapping built-in types ----------------------- - -As we saw in section ootypesystem defines a set of types that take -advantage of built-in types offered by the platform. - -For the sake of simplicity we decided to write wrappers -around .NET classes in order to match the signatures required by -pypylib.dll: - -=================== =========================================== -ootype CLI -=================== =========================================== -String System.String -StringBuilder System.Text.StringBuilder -List System.Collections.Generic.List -Dict System.Collections.Generic.Dictionary -CustomDict pypy.runtime.Dict -DictItemsIterator pypy.runtime.DictItemsIterator -=================== =========================================== - -Wrappers exploit inheritance for wrapping the original classes, so, -for example, pypy.runtime.List is a subclass of -System.Collections.Generic.List that provides methods whose names -match those found in the _GENERIC_METHODS of ootype.List - -The only exception to this rule is the String class, which is not -wrapped since in .NET we can not subclass System.String. Instead, we -provide a bunch of static methods in pypylib.dll that implement the -methods declared by ootype.String._GENERIC_METHODS, then we call them -by explicitly passing the string object in the argument list. - - -Mapping instructions --------------------- - -PyPy's low level operations are expressed in Static Single Information -(SSI) form, such as this:: - - v2 = int_add(v0, v1) - -By contrast the CLI virtual machine is stack based, which means the -each operation pops its arguments from the top of the stacks and -pushes its result there. The most straightforward way to translate SSI -operations into stack based operations is to explicitly load the -arguments and store the result into the appropriate places:: - - LOAD v0 - LOAD v1 - int_add - STORE v2 - -The code produced works correctly but has some inefficiency issues that -can be addressed during the optimization phase. - -The CLI Virtual Machine is fairly expressive, so the conversion -between PyPy's low level operations and CLI instruction is relatively -simple: many operations maps directly to the corresponding -instruction, e.g int_add and sub. - -By contrast some instructions do not have a direct correspondent and -have to be rendered as a sequence of CLI instructions: this is the -case of the "less-equal" and "greater-equal" family of instructions, -that are rendered as "greater" or "less" followed by a boolean "not", -respectively. - -Finally, there are some instructions that cannot be rendered directly -without increasing the complexity of the code generator, such as -int_abs (which returns the absolute value of its argument). These -operations are translated by calling some helper function written in -C#. - -The code that implements the mapping is in the modules opcodes.py. - -Mapping exceptions ------------------- - -Both RPython and CLI have their own set of exception classes: some of -these are pretty similar; e.g., we have OverflowError, -ZeroDivisionError and IndexError on the first side and -OverflowException, DivideByZeroException and IndexOutOfRangeException -on the other side. - -The first attempt was to map RPython classes to their corresponding -CLI ones: this worked for simple cases, but it would have triggered -subtle bugs in more complex ones, because the two exception -hierarchies don't completely overlap. - -At the moment we've chosen to build an RPython exception hierarchy -completely independent from the CLI one, but this means that we can't -rely on exceptions raised by built-in operations. The currently -implemented solution is to do an exception translation on-the-fly. - -As an example consider the RPython int_add_ovf operation, that sums -two integers and raises an OverflowError exception in case of -overflow. For implementing it we can use the built-in add.ovf CLI -instruction that raises System.OverflowException when the result -overflows, catch that exception and throw a new one:: - - .try - { - ldarg 'x_0' - ldarg 'y_0' - add.ovf - stloc 'v1' - leave __check_block_2 - } - catch [mscorlib]System.OverflowException - { - newobj instance void class OverflowError::.ctor() - throw - } - - -Translating flow graphs ------------------------ - -As we saw previously in PyPy function and method bodies are -represented by flow graphs that we need to translate CLI IL code. Flow -graphs are expressed in a format that is very suitable for being -translated to low level code, so that phase is quite straightforward, -though the code is a bit involved because we need to take care of three -different types of blocks. - -The code doing this work is located in the Function.render -method in the file function.py. - -First of all it searches for variable names and types used by -each block; once they are collected it emits a .local IL -statement used for indicating the virtual machine the number and type -of local variables used. - -Then it sequentially renders all blocks in the graph, starting from the -start block; special care is taken for the return block which is -always rendered at last to meet CLI requirements. - -Each block starts with an unique label that is used for jumping -across, followed by the low level instructions the block is composed -of; finally there is some code that jumps to the appropriate next -block. - -Conditional and unconditional jumps are rendered with their -corresponding IL instructions: brtrue, brfalse. - -Blocks that needs to catch exceptions use the native facilities -offered by the CLI virtual machine: the entire block is surrounded by -a .try statement followed by as many catch as needed: each catching -sub-block then branches to the appropriate block:: - - - # RPython - try: - # block0 - ... - except ValueError: - # block1 - ... - except TypeError: - # block2 - ... - - // IL - block0: - .try { - ... - leave block3 - } - catch ValueError { - ... - leave block1 - } - catch TypeError { - ... - leave block2 - } - block1: - ... - br block3 - block2: - ... - br block3 - block3: - ... - -There is also an experimental feature that makes GenCLI to use its own -exception handling mechanism instead of relying on the .NET -one. Surprisingly enough, benchmarks are about 40% faster with our own -exception handling machinery. - - -Translating classes -------------------- - -As we saw previously, the semantic of ootypesystem classes -is very similar to the .NET one, so the translation is mostly -straightforward. - -The related code is located in the module class\_.py. Rendered classes -are composed of four parts: - - - fields; - - user defined methods; - - default constructor; - - the ToString method, mainly for testing purposes - -Since ootype implicitly assumes all method calls to be late bound, as -an optimization before rendering the classes we search for methods -that are not overridden in subclasses, and declare as "virtual" only -the one that needs to. - -The constructor does nothing more than calling the base class -constructor and initializing class fields to their default value. - -Inheritance is straightforward too, as it is natively supported by -CLI. The only noticeable thing is that we map ootypesystem's ROOT -class to the CLI equivalent System.Object. - -The Runtime Environment ------------------------ - -The runtime environment is a collection of helper classes and -functions used and referenced by many of the GenCLI submodules. It is -written in C#, compiled to a DLL (Dynamic Link Library), then linked -to generated code at compile-time. - -The DLL is called pypylib and is composed of three parts: - - - a set of helper functions used to implements complex RPython - low-level instructions such as runtimenew and ooparse_int; - - - a set of helper classes wrapping built-in types - - - a set of helpers used by the test framework - - -The first two parts are contained in the pypy.runtime namespace, while -the third is in the pypy.test one. - - -Testing GenCLI -============== - From noreply at buildbot.pypy.org Thu Sep 5 12:46:38 2013 From: noreply at buildbot.pypy.org (Raemi) Date: Thu, 5 Sep 2013 12:46:38 +0200 (CEST) Subject: [pypy-commit] pypy stmgc-c4: remove duplicated logging Message-ID: <20130905104638.5CB4B1C0EE9@cobra.cs.uni-duesseldorf.de> Author: Remi Meier Branch: stmgc-c4 Changeset: r66790:b7324b5903a6 Date: 2013-09-05 12:45 +0200 http://bitbucket.org/pypy/pypy/changeset/b7324b5903a6/ Log: remove duplicated logging 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 @@ -586,8 +586,6 @@ operations = regalloc.prepare_loop(inputargs, operations, looptoken, clt.allgcrefs) - if logger: - logger.log_loop(inputargs, operations, -3, "rewritten") looppos = self.mc.get_relative_pos() frame_depth_no_fixed_size = self._assemble(regalloc, inputargs, operations) @@ -651,8 +649,6 @@ operations, self.current_clt.allgcrefs, self.current_clt.frame_info) - if logger: - logger.log_bridge(inputargs, operations, "rewritten") 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() 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 @@ -25,10 +25,6 @@ debug_start("jit-log-compiling-loop") logops = self._log_operations(inputargs, operations, ops_offset) debug_stop("jit-log-compiling-loop") - elif number == -3: - debug_start("jit-log-rewritten-loop") - logops = self._log_operations(inputargs, operations, ops_offset) - debug_stop("jit-log-rewritten-loop") else: debug_start("jit-log-opt-loop") debug_print("# Loop", number, '(%s)' % name, ":", type, @@ -43,10 +39,6 @@ debug_start("jit-log-noopt-bridge") logops = self._log_operations(inputargs, operations, ops_offset) debug_stop("jit-log-noopt-bridge") - elif extra == "rewritten": - debug_start("jit-log-rewritten-bridge") - logops = self._log_operations(inputargs, operations, ops_offset) - debug_stop("jit-log-rewritten-bridge") elif extra == "compiling": debug_start("jit-log-compiling-bridge") logops = self._log_operations(inputargs, operations, ops_offset) From noreply at buildbot.pypy.org Thu Sep 5 13:16:04 2013 From: noreply at buildbot.pypy.org (Raemi) Date: Thu, 5 Sep 2013 13:16:04 +0200 (CEST) Subject: [pypy-commit] pypy stmgc-c4: fix some merge leftovers Message-ID: <20130905111604.A75801C0710@cobra.cs.uni-duesseldorf.de> Author: Remi Meier Branch: stmgc-c4 Changeset: r66791:7162dd07c7a1 Date: 2013-09-05 13:15 +0200 http://bitbucket.org/pypy/pypy/changeset/7162dd07c7a1/ Log: fix some merge leftovers diff --git a/pypy/interpreter/pyopcode.py b/pypy/interpreter/pyopcode.py --- a/pypy/interpreter/pyopcode.py +++ b/pypy/interpreter/pyopcode.py @@ -199,7 +199,7 @@ else: next_instr = block.handle(self, unroller) elif opcode == opcodedesc.JUMP_ABSOLUTE.index: - next_instr = self.jump_absolute(oparg, ec) + return self.jump_absolute(oparg, ec) elif opcode == opcodedesc.BREAK_LOOP.index: next_instr = self.BREAK_LOOP(oparg, next_instr) elif opcode == opcodedesc.CONTINUE_LOOP.index: @@ -455,10 +455,10 @@ from rpython.rlib import rstm if rstm.should_break_transaction(): opcode = ord(co_code[next_instr]) - if opcode not in (self.opcodedesc.RETURN_VALUE.index, - self.opcodedesc.POP_TOP.index, - self.opcodedesc.LOAD_CONST.index, - self.opcodedesc.LOAD_FAST.index): + if opcode not in (opcodedesc.RETURN_VALUE.index, + opcodedesc.POP_TOP.index, + opcodedesc.LOAD_CONST.index, + opcodedesc.LOAD_FAST.index): return next_instr @jit.unroll_safe From noreply at buildbot.pypy.org Thu Sep 5 13:21:29 2013 From: noreply at buildbot.pypy.org (arigo) Date: Thu, 5 Sep 2013 13:21:29 +0200 (CEST) Subject: [pypy-commit] pypy stmgc-c4: Fix for running most non-stm C tests Message-ID: <20130905112129.8A90D1C0710@cobra.cs.uni-duesseldorf.de> Author: Armin Rigo Branch: stmgc-c4 Changeset: r66792:596a596bbd85 Date: 2013-09-05 13:20 +0200 http://bitbucket.org/pypy/pypy/changeset/596a596bbd85/ Log: Fix for running most non-stm C tests diff --git a/rpython/translator/c/src/rtyper.c b/rpython/translator/c/src/rtyper.c --- a/rpython/translator/c/src/rtyper.c +++ b/rpython/translator/c/src/rtyper.c @@ -16,7 +16,9 @@ char *RPyString_AsCharP(RPyString *rps) { +#ifdef RPY_STM rps = (RPyString *)stm_read_barrier((gcptr)rps); +#endif Signed len = RPyString_Size(rps); struct _RPyString_dump_t *dump = \ malloc(sizeof(struct _RPyString_dump_t) + len); From noreply at buildbot.pypy.org Thu Sep 5 13:28:45 2013 From: noreply at buildbot.pypy.org (arigo) Date: Thu, 5 Sep 2013 13:28:45 +0200 (CEST) Subject: [pypy-commit] pypy stmgc-c4: Fix Message-ID: <20130905112845.903E71C0710@cobra.cs.uni-duesseldorf.de> Author: Armin Rigo Branch: stmgc-c4 Changeset: r66793:88f1e893cd20 Date: 2013-09-05 13:28 +0200 http://bitbucket.org/pypy/pypy/changeset/88f1e893cd20/ Log: Fix diff --git a/rpython/translator/backendopt/writeanalyze.py b/rpython/translator/backendopt/writeanalyze.py --- a/rpython/translator/backendopt/writeanalyze.py +++ b/rpython/translator/backendopt/writeanalyze.py @@ -49,7 +49,7 @@ def analyze_external_call(self, op, seen=None): funcobj = op.args[0].value._obj - if funcobj.random_effects_on_gcobjs: + if getattr(funcobj, 'random_effects_on_gcobjs', False): return self.top_result() return graphanalyze.GraphAnalyzer.analyze_external_call(self, op, seen) From noreply at buildbot.pypy.org Thu Sep 5 13:44:39 2013 From: noreply at buildbot.pypy.org (arigo) Date: Thu, 5 Sep 2013 13:44:39 +0200 (CEST) Subject: [pypy-commit] pypy stmgc-c4: More merge fixes Message-ID: <20130905114439.EB0F71C0EE9@cobra.cs.uni-duesseldorf.de> Author: Armin Rigo Branch: stmgc-c4 Changeset: r66794:92f08aa9fa6c Date: 2013-09-05 13:43 +0200 http://bitbucket.org/pypy/pypy/changeset/92f08aa9fa6c/ Log: More merge fixes diff --git a/rpython/translator/stm/breakfinder.py b/rpython/translator/stm/breakfinder.py --- a/rpython/translator/stm/breakfinder.py +++ b/rpython/translator/stm/breakfinder.py @@ -1,5 +1,4 @@ from rpython.translator.backendopt import graphanalyze -from rpython.translator.simplify import get_funcobj TRANSACTION_BREAK = set([ diff --git a/rpython/translator/stm/inevitable.py b/rpython/translator/stm/inevitable.py --- a/rpython/translator/stm/inevitable.py +++ b/rpython/translator/stm/inevitable.py @@ -2,7 +2,6 @@ from rpython.translator.stm.writebarrier import is_immutable from rpython.flowspace.model import SpaceOperation, Constant from rpython.translator.unsimplify import varoftype -from rpython.translator.simplify import get_funcobj ALWAYS_ALLOW_OPERATIONS = set([ @@ -82,7 +81,7 @@ # # Function calls if op.opname == 'direct_call': - funcptr = get_funcobj(op.args[0].value) + funcptr = op.args[0].value._obj if not hasattr(funcptr, "external"): return False if getattr(funcptr, "transactionsafe", False): From noreply at buildbot.pypy.org Thu Sep 5 13:46:28 2013 From: noreply at buildbot.pypy.org (arigo) Date: Thu, 5 Sep 2013 13:46:28 +0200 (CEST) Subject: [pypy-commit] pypy stmgc-c4: Merge fix Message-ID: <20130905114628.A09DA1C0EE9@cobra.cs.uni-duesseldorf.de> Author: Armin Rigo Branch: stmgc-c4 Changeset: r66795:55788159fb46 Date: 2013-09-05 13:45 +0200 http://bitbucket.org/pypy/pypy/changeset/55788159fb46/ Log: Merge fix 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 @@ -254,7 +254,6 @@ def start_thread(args): bootstrapper.acquire(args) try: - rthread.gc_thread_prepare() # (this has no effect any more) ident = rthread.start_new_thread(bootstrapper.bootstrap, ()) except Exception, e: bootstrapper.release() # normally called by the new thread From noreply at buildbot.pypy.org Thu Sep 5 14:06:22 2013 From: noreply at buildbot.pypy.org (arigo) Date: Thu, 5 Sep 2013 14:06:22 +0200 (CEST) Subject: [pypy-commit] pypy stmgc-c4: Fix for test_lloperation Message-ID: <20130905120622.879551C0710@cobra.cs.uni-duesseldorf.de> Author: Armin Rigo Branch: stmgc-c4 Changeset: r66796:2aa408c80a97 Date: 2013-09-05 14:05 +0200 http://bitbucket.org/pypy/pypy/changeset/2aa408c80a97/ Log: Fix for test_lloperation diff --git a/rpython/rtyper/llinterp.py b/rpython/rtyper/llinterp.py --- a/rpython/rtyper/llinterp.py +++ b/rpython/rtyper/llinterp.py @@ -942,9 +942,39 @@ def _stm_not_implemented(self, *args): raise NotImplementedError - op_stm_writebarrier = _stm_not_implemented - op_stm_normalize_global = _stm_not_implemented + op_stm_initialize = _stm_not_implemented + op_stm_finalize = _stm_not_implemented + op_stm_perform_transaction = _stm_not_implemented + op_stm_should_break_transaction = _stm_not_implemented + op_stm_commit_transaction = _stm_not_implemented + op_stm_begin_inevitable_transaction = _stm_not_implemented + op_stm_barrier = _stm_not_implemented + op_stm_push_root = _stm_not_implemented + op_stm_pop_root_into = _stm_not_implemented + op_stm_get_adr_of_read_barrier_cache = _stm_not_implemented + op_stm_get_adr_of_private_rev_num = _stm_not_implemented + op_stm_enter_callback_call = _stm_not_implemented + op_stm_leave_callback_call = _stm_not_implemented + op_stm_get_atomic = _stm_not_implemented + op_stm_change_atomic = _stm_not_implemented + op_stm_set_transaction_length = _stm_not_implemented + op_stm_abort_info_push = _stm_not_implemented + op_stm_abort_info_pop = _stm_not_implemented + op_stm_inspect_abort_info = _stm_not_implemented + op_stm_threadlocal_get = _stm_not_implemented + op_stm_threadlocal_set = _stm_not_implemented + op_stm_threadlocalref_get = _stm_not_implemented + op_stm_threadlocalref_set = _stm_not_implemented + op_stm_hash = _stm_not_implemented + op_stm_id = _stm_not_implemented + op_stm_allocate = _stm_not_implemented + op_stm_weakref_allocate = _stm_not_implemented + op_stm_allocate_nonmovable_int_adr = _stm_not_implemented + op_stm_minor_collect = _stm_not_implemented + op_stm_major_collect = _stm_not_implemented + op_stm_abort_and_retry = _stm_not_implemented op_stm_become_inevitable = _stm_not_implemented + op_stm_clear_exception_data_on_abort = _stm_not_implemented # __________________________________________________________ # operations on addresses 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 @@ -672,6 +672,12 @@ def op_debug_stm_flush_barrier(): pass +def op_stm_ptr_eq(x, y): + return op_ptr_eq(x, y) + +def op_stm_get_tid(x): + raise NotImplementedError + # ____________________________________________________________ def get_op_impl(opname): From noreply at buildbot.pypy.org Thu Sep 5 14:13:12 2013 From: noreply at buildbot.pypy.org (arigo) Date: Thu, 5 Sep 2013 14:13:12 +0200 (CEST) Subject: [pypy-commit] pypy stmgc-c4: Accept DelayedPointers here too Message-ID: <20130905121312.957E31C0710@cobra.cs.uni-duesseldorf.de> Author: Armin Rigo Branch: stmgc-c4 Changeset: r66797:ae319563c727 Date: 2013-09-05 14:12 +0200 http://bitbucket.org/pypy/pypy/changeset/ae319563c727/ Log: Accept DelayedPointers here too diff --git a/rpython/translator/backendopt/writeanalyze.py b/rpython/translator/backendopt/writeanalyze.py --- a/rpython/translator/backendopt/writeanalyze.py +++ b/rpython/translator/backendopt/writeanalyze.py @@ -1,5 +1,6 @@ from rpython.flowspace.model import Variable from rpython.translator.backendopt import graphanalyze +from rpython.rtyper.lltypesystem import lltype top_set = object() empty_set = frozenset() @@ -48,8 +49,12 @@ return frozenset([("array", TYPE)]) def analyze_external_call(self, op, seen=None): - funcobj = op.args[0].value._obj - if getattr(funcobj, 'random_effects_on_gcobjs', False): + try: + funcobj = op.args[0].value._obj + random = funcobj.random_effects_on_gcobjs + except (AttributeError, lltype.DelayedPointer): + random = True + if random: return self.top_result() return graphanalyze.GraphAnalyzer.analyze_external_call(self, op, seen) From noreply at buildbot.pypy.org Thu Sep 5 15:14:05 2013 From: noreply at buildbot.pypy.org (Raemi) Date: Thu, 5 Sep 2013 15:14:05 +0200 (CEST) Subject: [pypy-commit] pypy stmgc-c4: fix bogus test Message-ID: <20130905131405.4C3CC1C0710@cobra.cs.uni-duesseldorf.de> Author: Remi Meier Branch: stmgc-c4 Changeset: r66798:58b2c26c0c1c Date: 2013-09-05 15:13 +0200 http://bitbucket.org/pypy/pypy/changeset/58b2c26c0c1c/ Log: fix bogus test diff --git a/rpython/jit/backend/llsupport/test/zrpy_gc_test.py b/rpython/jit/backend/llsupport/test/zrpy_gc_test.py --- a/rpython/jit/backend/llsupport/test/zrpy_gc_test.py +++ b/rpython/jit/backend/llsupport/test/zrpy_gc_test.py @@ -860,13 +860,14 @@ while a.i: driver.jit_merge_point(a=a) a.i -= 1 - print a.v def f(n, x, x0, x1, x2, x3, x4, x5, x6, x7, l, s): u = lltype.malloc(S) u.i = 10000 u.v = n inner(u) + assert u.i == 0 + assert u.v == n return n - 1, x, x0, x1, x2, x3, x4, x5, x6, x7, l, s From noreply at buildbot.pypy.org Thu Sep 5 15:35:35 2013 From: noreply at buildbot.pypy.org (arigo) Date: Thu, 5 Sep 2013 15:35:35 +0200 (CEST) Subject: [pypy-commit] pypy stmgc-c4: Fix Message-ID: <20130905133535.60B8E1C0710@cobra.cs.uni-duesseldorf.de> Author: Armin Rigo Branch: stmgc-c4 Changeset: r66799:8b7632f5ff7a Date: 2013-09-05 15:34 +0200 http://bitbucket.org/pypy/pypy/changeset/8b7632f5ff7a/ Log: Fix diff --git a/rpython/rlib/rstm.py b/rpython/rlib/rstm.py --- a/rpython/rlib/rstm.py +++ b/rpython/rlib/rstm.py @@ -77,25 +77,29 @@ @dont_look_inside def before_external_call(): - llop.stm_commit_transaction(lltype.Void) + if we_are_translated(): + llop.stm_commit_transaction(lltype.Void) before_external_call._dont_reach_me_in_del_ = True before_external_call._transaction_break_ = True @dont_look_inside def after_external_call(): - llop.stm_begin_inevitable_transaction(lltype.Void) + if we_are_translated(): + llop.stm_begin_inevitable_transaction(lltype.Void) after_external_call._dont_reach_me_in_del_ = True after_external_call._transaction_break_ = True @dont_look_inside def enter_callback_call(): - return llop.stm_enter_callback_call(lltype.Signed) + if we_are_translated(): + return llop.stm_enter_callback_call(lltype.Signed) enter_callback_call._dont_reach_me_in_del_ = True enter_callback_call._transaction_break_ = True @dont_look_inside def leave_callback_call(token): - llop.stm_leave_callback_call(lltype.Void, token) + if we_are_translated(): + llop.stm_leave_callback_call(lltype.Void, token) leave_callback_call._dont_reach_me_in_del_ = True leave_callback_call._transaction_break_ = True From noreply at buildbot.pypy.org Thu Sep 5 15:35:36 2013 From: noreply at buildbot.pypy.org (arigo) Date: Thu, 5 Sep 2013 15:35:36 +0200 (CEST) Subject: [pypy-commit] pypy stmgc-c4: merge heads Message-ID: <20130905133536.846E51C0710@cobra.cs.uni-duesseldorf.de> Author: Armin Rigo Branch: stmgc-c4 Changeset: r66800:fb08fabf15b6 Date: 2013-09-05 15:34 +0200 http://bitbucket.org/pypy/pypy/changeset/fb08fabf15b6/ Log: merge heads diff --git a/rpython/jit/backend/llsupport/test/zrpy_gc_test.py b/rpython/jit/backend/llsupport/test/zrpy_gc_test.py --- a/rpython/jit/backend/llsupport/test/zrpy_gc_test.py +++ b/rpython/jit/backend/llsupport/test/zrpy_gc_test.py @@ -860,13 +860,14 @@ while a.i: driver.jit_merge_point(a=a) a.i -= 1 - print a.v def f(n, x, x0, x1, x2, x3, x4, x5, x6, x7, l, s): u = lltype.malloc(S) u.i = 10000 u.v = n inner(u) + assert u.i == 0 + assert u.v == n return n - 1, x, x0, x1, x2, x3, x4, x5, x6, x7, l, s From noreply at buildbot.pypy.org Thu Sep 5 15:55:29 2013 From: noreply at buildbot.pypy.org (arigo) Date: Thu, 5 Sep 2013 15:55:29 +0200 (CEST) Subject: [pypy-commit] pypy stmgc-c4: Skip this test when running on top of CPython Message-ID: <20130905135529.252251C0710@cobra.cs.uni-duesseldorf.de> Author: Armin Rigo Branch: stmgc-c4 Changeset: r66801:7f9388621e23 Date: 2013-09-05 15:45 +0200 http://bitbucket.org/pypy/pypy/changeset/7f9388621e23/ Log: Skip this test when running on top of CPython diff --git a/pypy/module/__pypy__/test/test_signal.py b/pypy/module/__pypy__/test/test_signal.py --- a/pypy/module/__pypy__/test/test_signal.py +++ b/pypy/module/__pypy__/test/test_signal.py @@ -25,6 +25,9 @@ __pypy__.thread._signals_enter() def test_enable_signals(self): + if not self.run_on_pypy: + skip("needs non-main-thread signals") + import __pypy__, thread, signal, time, sys def subthread(): diff --git a/pypy/module/thread/test/support.py b/pypy/module/thread/test/support.py --- a/pypy/module/thread/test/support.py +++ b/pypy/module/thread/test/support.py @@ -1,7 +1,7 @@ import gc import time import thread -import os +import os, sys import errno from pypy.interpreter.gateway import interp2app, unwrap_spec @@ -60,6 +60,7 @@ def py_timeout_killer(self, *args, **kwargs): timeout_killer(*args, **kwargs) cls.w_timeout_killer = cls.space.wrap(py_timeout_killer) + run_on_pypy = True else: @unwrap_spec(delay=int) def py_waitfor(space, w_condition, delay=1): @@ -75,8 +76,10 @@ ]) timeout_killer(*args, **kwargs) cls.w_timeout_killer = cls.space.wrap(interp2app(py_timeout_killer)) + run_on_pypy = '__pypy__' in sys.builtin_module_names cls.w_busywait = cls.space.appexec([], """(): import time return time.sleep """) + cls.w_run_on_pypy = cls.space.wrap(run_on_pypy) From noreply at buildbot.pypy.org Thu Sep 5 16:07:54 2013 From: noreply at buildbot.pypy.org (arigo) Date: Thu, 5 Sep 2013 16:07:54 +0200 (CEST) Subject: [pypy-commit] pypy stmgc-c4: Fix Message-ID: <20130905140754.3510B1C0710@cobra.cs.uni-duesseldorf.de> Author: Armin Rigo Branch: stmgc-c4 Changeset: r66802:b1e4685cb239 Date: 2013-09-05 16:06 +0200 http://bitbucket.org/pypy/pypy/changeset/b1e4685cb239/ Log: Fix 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 @@ -342,9 +342,9 @@ metainterp_sd.profiler.start_backend() debug_start("jit-backend") try: - asminfo, new_ops = do_compile_loop(metainterp_sd, loop.inputargs, - operations, original_jitcell_token, - name=loopname) + asminfo = do_compile_loop(metainterp_sd, loop.inputargs, + operations, original_jitcell_token, + name=loopname) finally: debug_stop("jit-backend") metainterp_sd.profiler.end_backend() @@ -360,7 +360,7 @@ ops_offset = asminfo.ops_offset else: ops_offset = None - metainterp_sd.logger_ops.log_loop(loop.inputargs, new_ops, n, + metainterp_sd.logger_ops.log_loop(loop.inputargs, loop.operations, n, type, ops_offset, name=loopname) # @@ -386,9 +386,9 @@ metainterp_sd.profiler.start_backend() debug_start("jit-backend") try: - asminfo, new_ops = do_compile_bridge(metainterp_sd, faildescr, - inputargs, operations, - original_loop_token) + asminfo = do_compile_bridge(metainterp_sd, faildescr, + inputargs, operations, + original_loop_token) finally: debug_stop("jit-backend") metainterp_sd.profiler.end_backend() @@ -403,7 +403,7 @@ ops_offset = asminfo.ops_offset else: ops_offset = None - metainterp_sd.logger_ops.log_bridge(inputargs, new_ops, None, faildescr, + metainterp_sd.logger_ops.log_bridge(inputargs, operations, None, faildescr, ops_offset) # #if metainterp_sd.warmrunnerdesc is not None: # for tests From noreply at buildbot.pypy.org Thu Sep 5 16:10:00 2013 From: noreply at buildbot.pypy.org (arigo) Date: Thu, 5 Sep 2013 16:10:00 +0200 (CEST) Subject: [pypy-commit] pypy stmgc-c4: Use a regexp to drop the "1#" at the start of stm pypylog files. Message-ID: <20130905141000.AB03B1C0710@cobra.cs.uni-duesseldorf.de> Author: Armin Rigo Branch: stmgc-c4 Changeset: r66803:4c03d4d79569 Date: 2013-09-05 16:09 +0200 http://bitbucket.org/pypy/pypy/changeset/4c03d4d79569/ Log: Use a regexp to drop the "1#" at the start of stm pypylog files. Otherwise, it would drop everything before a "#" used as a comment. 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 @@ -7,6 +7,8 @@ import optparse import re +r_skip_thread = re.compile(r'^(\d+#)?') + def get_timestamp(line): match = re.match(r'\[([0-9a-f]*)\] .*', line) return int(match.group(1), 16) @@ -17,13 +19,13 @@ time0 = None lines = iter(log) for line in lines: - line = line[line.find("#") + 1:].strip() + line = r_skip_thread.sub('', line).strip() if time0 is None and line.startswith('['): time0 = get_timestamp(line) if '{jit-mem-looptoken-' in line: time_now = get_timestamp(line) - time0 text = lines.next() - text = text[text.find("#") + 1:].strip() + text = r_skip_thread.sub('', text).strip() if text.startswith('allocating Loop #'): loops += 1 elif text.startswith('allocating Bridge #'): 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 @@ -3,12 +3,15 @@ in a nicer fashion """ +import re from rpython.jit.tool.oparser_model import get_model - from rpython.jit.metainterp.resoperation import rop, ResOperation, \ ResOpWithDescr, N_aryOp, \ UnaryOp, PlainResOp +r_skip_thread = re.compile(r'^(\d+#)?') + + class ParseError(Exception): pass @@ -297,7 +300,7 @@ newlines = [] first_comment = None for line in lines: - line = line[line.find('#')+1:].strip() + line = r_skip_thread.sub('', line).strip() # for simplicity comments are not allowed on # debug_merge_point lines if '#' in line and 'debug_merge_point(' not in line: From noreply at buildbot.pypy.org Thu Sep 5 16:35:06 2013 From: noreply at buildbot.pypy.org (arigo) Date: Thu, 5 Sep 2013 16:35:06 +0200 (CEST) Subject: [pypy-commit] pypy stmgc-c4: Argh argh argh! This comes from an insufficiently-tested checkin by Message-ID: <20130905143506.873601C0EE9@cobra.cs.uni-duesseldorf.de> Author: Armin Rigo Branch: stmgc-c4 Changeset: r66804:5ebc24517995 Date: 2013-09-05 16:34 +0200 http://bitbucket.org/pypy/pypy/changeset/5ebc24517995/ Log: Argh argh argh! This comes from an insufficiently-tested checkin by me long ago. :-( diff --git a/rpython/translator/backendopt/writeanalyze.py b/rpython/translator/backendopt/writeanalyze.py --- a/rpython/translator/backendopt/writeanalyze.py +++ b/rpython/translator/backendopt/writeanalyze.py @@ -40,7 +40,7 @@ if graphinfo is None or not graphinfo.is_fresh_malloc(op.args[0]): return frozenset([ ("struct", op.args[0].concretetype, op.args[1].value)]) - elif op.opname == ("setarrayitem", "setinteriorfield"): + elif op.opname == "setarrayitem": if graphinfo is None or not graphinfo.is_fresh_malloc(op.args[0]): return self._array_result(op.args[0].concretetype) return empty_set From noreply at buildbot.pypy.org Thu Sep 5 16:59:37 2013 From: noreply at buildbot.pypy.org (arigo) Date: Thu, 5 Sep 2013 16:59:37 +0200 (CEST) Subject: [pypy-commit] pypy stmgc-c4: Fix for test_zll_stress_*. Message-ID: <20130905145937.D32B11C36AC@cobra.cs.uni-duesseldorf.de> Author: Armin Rigo Branch: stmgc-c4 Changeset: r66805:9c83120fc819 Date: 2013-09-05 16:58 +0200 http://bitbucket.org/pypy/pypy/changeset/9c83120fc819/ Log: Fix for test_zll_stress_*. diff --git a/rpython/rlib/rgc.py b/rpython/rlib/rgc.py --- a/rpython/rlib/rgc.py +++ b/rpython/rlib/rgc.py @@ -403,7 +403,11 @@ if we_are_translated(): return lltype.cast_ptr_to_int(gcref) else: - return id(gcref._x) + from rpython.rtyper import annlowlevel + from rpython.rtyper.lltypesystem import llmemory, rffi + p = annlowlevel.cast_instance_to_base_ptr(gcref._x) + p = lltype.cast_opaque_ptr(llmemory.GCREF, p) + return rffi.cast(lltype.Signed, p) def dump_rpy_heap(fd): "NOT_RPYTHON" From noreply at buildbot.pypy.org Thu Sep 5 17:01:22 2013 From: noreply at buildbot.pypy.org (arigo) Date: Thu, 5 Sep 2013 17:01:22 +0200 (CEST) Subject: [pypy-commit] pypy stmgc-c4: fix test Message-ID: <20130905150122.35B671C36AC@cobra.cs.uni-duesseldorf.de> Author: Armin Rigo Branch: stmgc-c4 Changeset: r66806:f5f6266b122f Date: 2013-09-05 17:00 +0200 http://bitbucket.org/pypy/pypy/changeset/f5f6266b122f/ Log: fix 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 @@ -2183,13 +2183,13 @@ del record[:] p0 = BoxPtr() operations = [ - ResOperation(rop.COND_CALL_GC_WB, [p0, ConstInt(0)], None, + ResOperation(rop.COND_CALL_GC_WB, [p0], None, descr=WriteBarrierDescr()), ResOperation(rop.FINISH, [p0], None, descr=BasicFinalDescr(0)) ] inputargs = [p0] looptoken = JitCellToken() - self.cpu.compile_loop(inputargs, operations, looptoken) + self.cpu.compile_loop(None, inputargs, operations, looptoken) fail = self.cpu.execute_token(looptoken, sgcref) assert fail.identifier == 1 res = self.cpu.get_latest_value_ref(0) From noreply at buildbot.pypy.org Thu Sep 5 17:09:43 2013 From: noreply at buildbot.pypy.org (vext01) Date: Thu, 5 Sep 2013 17:09:43 +0200 (CEST) Subject: [pypy-commit] jitviewer argparse-collect: (RichardN, Edd) Add the jitviewer path to PYTHONPATH automatically. Message-ID: <20130905150943.D803D1C0710@cobra.cs.uni-duesseldorf.de> Author: Edd Barrett Branch: argparse-collect Changeset: r229:f623ba2c70b0 Date: 2013-08-30 16:19 +0100 http://bitbucket.org/pypy/jitviewer/changeset/f623ba2c70b0/ Log: (RichardN, Edd) Add the jitviewer path to PYTHONPATH automatically. diff --git a/bin/jitviewer.py b/bin/jitviewer.py --- a/bin/jitviewer.py +++ b/bin/jitviewer.py @@ -1,4 +1,10 @@ #!/usr/bin/env pypy import sys +import os.path + +script_path = os.path.abspath(__file__) +pythonpath = os.path.dirname(os.path.dirname(script_path)) +sys.path.append(pythonpath) + from _jitviewer.app import main main(sys.argv) From noreply at buildbot.pypy.org Thu Sep 5 17:09:45 2013 From: noreply at buildbot.pypy.org (vext01) Date: Thu, 5 Sep 2013 17:09:45 +0200 (CEST) Subject: [pypy-commit] jitviewer argparse-collect: (RichardN, Edd) Remove broken import path hack. Message-ID: <20130905150945.195BF1C0710@cobra.cs.uni-duesseldorf.de> Author: Edd Barrett Branch: argparse-collect Changeset: r230:fe69b9239a69 Date: 2013-08-30 16:24 +0100 http://bitbucket.org/pypy/jitviewer/changeset/fe69b9239a69/ Log: (RichardN, Edd) Remove broken import path hack. diff --git a/_jitviewer/app.py b/_jitviewer/app.py --- a/_jitviewer/app.py +++ b/_jitviewer/app.py @@ -21,11 +21,6 @@ import os.path try: - import _jitviewer -except ImportError: - sys.path.insert(0, os.path.abspath(os.path.join(__file__, '..', '..'))) - -try: import pypy except ImportError: import __pypy__ From noreply at buildbot.pypy.org Thu Sep 5 17:09:46 2013 From: noreply at buildbot.pypy.org (vext01) Date: Thu, 5 Sep 2013 17:09:46 +0200 (CEST) Subject: [pypy-commit] jitviewer argparse-collect: Add the ability to collect the log file right now. Message-ID: <20130905150946.415F41C0710@cobra.cs.uni-duesseldorf.de> Author: Edd Barrett Branch: argparse-collect Changeset: r231:1a80997236ab Date: 2013-08-30 17:15 +0100 http://bitbucket.org/pypy/jitviewer/changeset/1a80997236ab/ Log: Add the ability to collect the log file right now. We lose the ability to select port. The next commit will convert jitviewer to use argparse. diff too long, truncating to 2000 out of 3866 lines diff --git a/_jitviewer/app.py b/_jitviewer/app.py --- a/_jitviewer/app.py +++ b/_jitviewer/app.py @@ -194,26 +194,64 @@ orig___init__(self2, *args, **kwds) BaseServer.__init__ = __init__ +def collect_log(interp, args, logpath="log.pypylog"): + """ Collect a log file using pypy """ + + # XXX Randomise log file name + # XXX Search path + + import subprocess + print("prog: %s args: %s" % (interp, args)) + + p = subprocess.Popen([interp] + args, + env={"PYPYLOG" : "jit-log-opt,jit-backend:%s" % (logpath, )} + ) + p.communicate() + # We don't check the return status. The user may want to see traces + # for a failing program! + return os.path.abspath(logpath) + def main(argv, run_app=True): if not '__pypy__' in sys.builtin_module_names: print "Please run it using pypy-c" sys.exit(1) # + # XXX use argparse server_mode = True + collect_mode = False if '--qt' in argv: server_mode = False argv.remove('--qt') + if '--collect' in argv: + prog_args = argv[argv.index('--collect')+1:] + prog = prog_args[0] + args = prog_args[1:] + collect_mode = True + argv.remove('--collect') # - if len(argv) != 2 and len(argv) != 3: + if not collect_mode and len(argv) != 2 and len(argv) != 3: print __doc__ sys.exit(1) - filename = argv[1] + + if collect_mode: + print("YO COLLECT MODE") + print(72 * ":") + filename = collect_log(prog, args) + port = 5000 # XXX ugh + else: + print("FUDGE") + print(72 * ":") + # XXX we really need argparse, as we cant specify port if collecting now + filename = argv[1] + + if len(argv) != 3: + port = 5000 + else: + port = int(argv[2]) + extra_path = os.path.dirname(filename) - if len(argv) != 3: - port = 5000 - else: - port = int(argv[2]) storage = LoopStorage(extra_path) + log, loops = import_log(filename, ParserWithHtmlRepr) parse_log_counts(extract_category(log, 'jit-backend-count'), loops) storage.loops = [loop for loop in loops @@ -226,7 +264,7 @@ app.route('/loop')(server.loop) if run_app: def run(): - app.run(use_reloader=bool(os.environ.get('JITVIEWER_USE_RELOADER', True)), host='0.0.0.0', port=port) + app.run(use_reloader=bool(os.environ.get('JITVIEWER_USE_RELOADER', False)), host='0.0.0.0', port=port) if server_mode: run() diff --git a/log.pypylog b/log.pypylog --- a/log.pypylog +++ b/log.pypylog @@ -1,3117 +1,699 @@ -[19c473e15553] {jit-backend-dump +[d4bd435c340] {jit-backend-dump BACKEND x86_64 -SYS_EXECUTABLE python -CODE_DUMP @7fe7c97fa000 +0 48894D58488945604889556848895D70488975784889BD800000004C8985880000004C898D900000004C8995980000004C89A5A00000004C89ADA80000004C89B5B00000004C89BDB8000000584889452058488945104889E84C8BBC24880000004C8BB424800000004C8B6C24784C8B642470488B5C2468488B6C24604881C498000000C3 -[19c473e25f71] jit-backend-dump} -[19c473e2c5ce] {jit-backend-dump +SYS_EXECUTABLE pypy +CODE_DUMP @29dd4436000 +0 48894D58488945604889556848895D70488975784889BD800000004C8985880000004C898D900000004C8995980000004C89A5A00000004C89ADA80000004C89B5B00000004C89BDB8000000584889452058488945104889E848BB30CF61CD9902000048832B084C8BBC24880000004C8BB424800000004C8B6C24784C8B642470488B5C2468488B6C24604881C498000000C3 +[d4bd43dff40] jit-backend-dump} +[d4bd43e968a] {jit-backend-dump BACKEND x86_64 -SYS_EXECUTABLE python -CODE_DUMP @7fe7c97fa085 +0 48894D58488945604889556848895D70488975784889BD800000004C8985880000004C898D900000004C8995980000004C89A5A00000004C89ADA80000004C89B5B00000004C89BDB8000000488B1C2508E6150348C7042500E615030000000048C7042508E615030000000048895D38584889452058488945104889E84C8BBC24880000004C8BB424800000004C8B6C24784C8B642470488B5C2468488B6C24604881C498000000C3 -[19c473e2ecc8] jit-backend-dump} -[19c473e31f04] {jit-backend-dump +SYS_EXECUTABLE pypy +CODE_DUMP @29dd4436093 +0 48894D58488945604889556848895D70488975784889BD800000004C8985880000004C898D900000004C8995980000004C89A5A00000004C89ADA80000004C89B5B00000004C89BDB800000049BB48D3E5CE99020000498B1B49BB40D3E5CE9902000049C7030000000049BB48D3E5CE9902000049C7030000000048895D38584889452058488945104889E848BB30CF61CD9902000048832B084C8BBC24880000004C8BB424800000004C8B6C24784C8B642470488B5C2468488B6C24604881C498000000C3 +[d4bd43f3eaa] jit-backend-dump} +[d4bd43f8304] {jit-backend-dump BACKEND x86_64 -SYS_EXECUTABLE python -CODE_DUMP @7fe7c97fa12e +0 4889455848894D60488955684889757048897D784C8985800000004C898D880000004C899590000000488B7C240841BBB064120141FFD3488B4558488B4D60488B5568488B7570488B7D784C8B85800000004C8B8D880000004C8B9590000000C20800 -[19c473e338a2] jit-backend-dump} -[19c473e366e6] {jit-backend-dump +SYS_EXECUTABLE pypy +CODE_DUMP @29dd4436159 +0 4889455848894D60488955684889757048897D784C8985800000004C898D880000004C899590000000488B7C240849BBD01AD1CC9902000041FFD3488B4558488B4D60488B5568488B7570488B7D784C8B85800000004C8B8D880000004C8B9590000000C20800 +[d4bd440fc6c] jit-backend-dump} +[d4bd441924a] {jit-backend-dump BACKEND x86_64 -SYS_EXECUTABLE python -CODE_DUMP @7fe7c97fa191 +0 4889455848894D60488955684889757048897D784C8985800000004C898D880000004C899590000000488B7C240841BBF065120141FFD3488B442408F6400480488B4558488B4D60488B5568488B7570488B7D784C8B85800000004C8B8D880000004C8B9590000000C20800 -[19c473e38072] jit-backend-dump} -[19c473e3b5e9] {jit-backend-dump +SYS_EXECUTABLE pypy +CODE_DUMP @29dd44361c0 +0 4889455848894D60488955684889757048897D784C8985800000004C898D880000004C899590000000488B7C240849BB101CD1CC9902000041FFD3488B442408F6400480488B4558488B4D60488B5568488B7570488B7D784C8B85800000004C8B8D880000004C8B9590000000C20800 +[d4bd441fdd0] jit-backend-dump} +[d4bd457435c] {jit-backend-dump BACKEND x86_64 -SYS_EXECUTABLE python -CODE_DUMP @7fe7c97fa1fd +0 4883EC384889442408F20F114424184889EF48895C24284C89642430488B1C2508E615034C8B242500E6150348C7042500E615030000000048C7042508E615030000000041BBB064120141FFD3F20F10442418488B44240848891C2508E615034C89242500E61503488B5C24284C8B642430488D642438C3 -[19c473e3d069] jit-backend-dump} -[19c473e40c38] {jit-backend-dump +SYS_EXECUTABLE pypy +CODE_DUMP @29dd4436230 +0 4883EC384889442408F20F114424184889EF48895C24284C8964243049BB48D3E5CE99020000498B1B49BB40D3E5CE990200004D8B2349BB40D3E5CE9902000049C7030000000049BB48D3E5CE9902000049C7030000000049BBD01AD1CC9902000041FFD3F20F10442418488B44240849BB48D3E5CE9902000049891B49BB40D3E5CE990200004D8923488B5C24284C8B642430488D642438C3 +[d4bd457e70a] jit-backend-dump} +[d4bd4586ce6] {jit-backend-dump BACKEND x86_64 -SYS_EXECUTABLE python -CODE_DUMP @7fe7c97fa275 +0 48894D58488945604889556848895D70488975784889BD800000004C8985880000004C898D900000004C8995980000004C89A5A00000004C89ADA80000004C89B5B00000004C89BDB8000000F20F1185C0000000F20F118DC8000000F20F1195D0000000F20F119DD8000000F20F11A5E0000000F20F11ADE8000000F20F11B5F0000000F20F11BDF8000000F2440F118500010000F2440F118D08010000F2440F119510010000F2440F119D18010000F2440F11A520010000F2440F11AD28010000F2440F11B530010000488B4C240848894D20488B7424104889EF4883EC0848C7452810000000488B0C2508E6150348894D38488B1C2500E6150348C7042500E615030000000048C7042508E615030000000041BB60DBE80041FFD34889C5488B4D3848C745380000000048890C2508E6150348891C2500E615034883C40848C745280000000048C7452000000000488B4D58488B4560488B5568488B5D70488B7578488BBD800000004C8B85880000004C8B8D900000004C8B95980000004C8BA5A00000004C8BADA80000004C8BB5B00000004C8BBDB8000000F20F1085C0000000F20F108DC8000000F20F1095D0000000F20F109DD8000000F20F10A5E0000000F20F10ADE8000000F20F10B5F0000000F20F10BDF8000000F2440F108500010000F2440F108D08010000F2440F109510010000F2440F109D18010000F2440F10A520010000F2440F10AD28010000F2440F10B530010000C3 -[19c473e45561] jit-backend-dump} -[19c473e467bb] {jit-backend-dump +SYS_EXECUTABLE pypy +CODE_DUMP @29dd44362ca +0 48894D58488945604889556848895D70488975784889BD800000004C8985880000004C898D900000004C8995980000004C89A5A00000004C89ADA80000004C89B5B00000004C89BDB8000000F20F1185C0000000F20F118DC8000000F20F1195D0000000F20F119DD8000000F20F11A5E0000000F20F11ADE8000000F20F11B5F0000000F20F11BDF8000000F2440F118500010000F2440F118D08010000F2440F119510010000F2440F119D18010000F2440F11A520010000F2440F11AD28010000F2440F11B530010000488B4C240848894D20488B7424104889EF4883EC0849BB48D3E5CE99020000498B0B48894D3849BB40D3E5CE99020000498B1B49BB40D3E5CE9902000049C7030000000049BB48D3E5CE9902000049C7030000000049BB90D89FCC9902000041FFD34889C5488B4D3848C745380000000049BB48D3E5CE9902000049890B49BB40D3E5CE9902000049891B4883C40849BB30CF61CD99020000498B1B488943F848C7452000000000488B4D58488B4560488B5568488B5D70488B7578488BBD800000004C8B85880000004C8B8D900000004C8B95980000004C8BA5A00000004C8BADA80000004C8BB5B00000004C8BBDB8000000F20F1085C0000000F20F108DC8000000F20F1095D0000000F20F109DD8000000F20F10A5E0000000F20F10ADE8000000F20F10B5F0000000F20F10BDF8000000F2440F108500010000F2440F108D08010000F2440F109510010000F2440F109D18010000F2440F10A520010000F2440F10AD28010000F2440F10B530010000C3 +[d4bd459ae14] jit-backend-dump} +[d4bd459f028] {jit-backend-dump BACKEND x86_64 -SYS_EXECUTABLE python -CODE_DUMP @7fe7c97fa491 +0 48894D58488945604889556848895D70488975784889BD800000004C8985880000004C898D900000004C8995980000004C89A5A00000004C89ADA80000004C89B5B00000004C89BDB8000000F20F1185C0000000F20F118DC8000000F20F1195D0000000F20F119DD8000000F20F11A5E0000000F20F11ADE8000000F20F11B5F0000000F20F11BDF8000000F2440F118500010000F2440F118D08010000F2440F119510010000F2440F119D18010000F2440F11A520010000F2440F11AD28010000F2440F11B530010000584889452058488945104889E84C8BBC24880000004C8BB424800000004C8B6C24784C8B642470488B5C2468488B6C24604881C498000000C3 -[19c473e48f8b] jit-backend-dump} -[19c473e4a206] {jit-backend-dump +SYS_EXECUTABLE pypy +CODE_DUMP @29dd4436509 +0 48894D58488945604889556848895D70488975784889BD800000004C8985880000004C898D900000004C8995980000004C89A5A00000004C89ADA80000004C89B5B00000004C89BDB8000000F20F1185C0000000F20F118DC8000000F20F1195D0000000F20F119DD8000000F20F11A5E0000000F20F11ADE8000000F20F11B5F0000000F20F11BDF8000000F2440F118500010000F2440F118D08010000F2440F119510010000F2440F119D18010000F2440F11A520010000F2440F11AD28010000F2440F11B530010000584889452058488945104889E848BB30CF61CD9902000048832B084C8BBC24880000004C8BB424800000004C8B6C24784C8B642470488B5C2468488B6C24604881C498000000C3 +[d4bd45aa7fc] jit-backend-dump} +[d4bd45ae4f6] {jit-backend-dump BACKEND x86_64 -SYS_EXECUTABLE python -CODE_DUMP @7fe7c97fa595 +0 48894D58488945604889556848895D70488975784889BD800000004C8985880000004C898D900000004C8995980000004C89A5A00000004C89ADA80000004C89B5B00000004C89BDB8000000F20F1185C0000000F20F118DC8000000F20F1195D0000000F20F119DD8000000F20F11A5E0000000F20F11ADE8000000F20F11B5F0000000F20F11BDF8000000F2440F118500010000F2440F118D08010000F2440F119510010000F2440F119D18010000F2440F11A520010000F2440F11AD28010000F2440F11B530010000488B1C2508E6150348C7042500E615030000000048C7042508E615030000000048895D38584889452058488945104889E84C8BBC24880000004C8BB424800000004C8B6C24784C8B642470488B5C2468488B6C24604881C498000000C3 -[19c473e56f01] jit-backend-dump} -[19c473e58819] {jit-backend-dump +SYS_EXECUTABLE pypy +CODE_DUMP @29dd443661b +0 48894D58488945604889556848895D70488975784889BD800000004C8985880000004C898D900000004C8995980000004C89A5A00000004C89ADA80000004C89B5B00000004C89BDB8000000F20F1185C0000000F20F118DC8000000F20F1195D0000000F20F119DD8000000F20F11A5E0000000F20F11ADE8000000F20F11B5F0000000F20F11BDF8000000F2440F118500010000F2440F118D08010000F2440F119510010000F2440F119D18010000F2440F11A520010000F2440F11AD28010000F2440F11B53001000049BB48D3E5CE99020000498B1B49BB40D3E5CE9902000049C7030000000049BB48D3E5CE9902000049C7030000000048895D38584889452058488945104889E848BB30CF61CD9902000048832B084C8BBC24880000004C8BB424800000004C8B6C24784C8B642470488B5C2468488B6C24604881C498000000C3 +[d4bd45cae42] jit-backend-dump} +[d4bd45cf30e] {jit-backend-dump BACKEND x86_64 -SYS_EXECUTABLE python -CODE_DUMP @7fe7c97fa6bd +0 4889455848894D60488955684889757048897D784C8985800000004C898D880000004C899590000000F20F1185C0000000F20F118DC8000000F20F1195D0000000F20F119DD8000000F20F11A5E0000000F20F11ADE8000000F20F11B5F0000000F20F11BDF8000000F2440F118500010000F2440F118D08010000F2440F119510010000F2440F119D18010000F2440F11A520010000F2440F11AD28010000F2440F11B530010000488B7C240841BBB064120141FFD3488B4558488B4D60488B5568488B7570488B7D784C8B85800000004C8B8D880000004C8B9590000000F20F1085C0000000F20F108DC8000000F20F1095D0000000F20F109DD8000000F20F10A5E0000000F20F10ADE8000000F20F10B5F0000000F20F10BDF8000000F2440F108500010000F2440F108D08010000F2440F109510010000F2440F109D18010000F2440F10A520010000F2440F10AD28010000F2440F10B530010000C20800 -[19c473e5b9af] jit-backend-dump} -[19c473e5cf8d] {jit-backend-dump +SYS_EXECUTABLE pypy +CODE_DUMP @29dd4436760 +0 4889455848894D60488955684889757048897D784C8985800000004C898D880000004C899590000000F20F1185C0000000F20F118DC8000000F20F1195D0000000F20F119DD8000000F20F11A5E0000000F20F11ADE8000000F20F11B5F0000000F20F11BDF8000000F2440F118500010000F2440F118D08010000F2440F119510010000F2440F119D18010000F2440F11A520010000F2440F11AD28010000F2440F11B530010000488B7C240849BBD01AD1CC9902000041FFD3488B4558488B4D60488B5568488B7570488B7D784C8B85800000004C8B8D880000004C8B9590000000F20F1085C0000000F20F108DC8000000F20F1095D0000000F20F109DD8000000F20F10A5E0000000F20F10ADE8000000F20F10B5F0000000F20F10BDF8000000F2440F108500010000F2440F108D08010000F2440F109510010000F2440F109D18010000F2440F10A520010000F2440F10AD28010000F2440F10B530010000C20800 +[d4bd45de666] jit-backend-dump} +[d4bd45e261c] {jit-backend-dump BACKEND x86_64 -SYS_EXECUTABLE python -CODE_DUMP @7fe7c97fa81e +0 4889455848894D60488955684889757048897D784C8985800000004C898D880000004C899590000000F20F1185C0000000F20F118DC8000000F20F1195D0000000F20F119DD8000000F20F11A5E0000000F20F11ADE8000000F20F11B5F0000000F20F11BDF8000000F2440F118500010000F2440F118D08010000F2440F119510010000F2440F119D18010000F2440F11A520010000F2440F11AD28010000F2440F11B530010000488B7C240841BBF065120141FFD3488B442408F6400480488B4558488B4D60488B5568488B7570488B7D784C8B85800000004C8B8D880000004C8B9590000000F20F1085C0000000F20F108DC8000000F20F1095D0000000F20F109DD8000000F20F10A5E0000000F20F10ADE8000000F20F10B5F0000000F20F10BDF8000000F2440F108500010000F2440F108D08010000F2440F109510010000F2440F109D18010000F2440F10A520010000F2440F10AD28010000F2440F10B530010000C20800 -[19c473e5fee0] jit-backend-dump} -[19c473e6101c] {jit-backend-dump +SYS_EXECUTABLE pypy +CODE_DUMP @29dd44368c5 +0 4889455848894D60488955684889757048897D784C8985800000004C898D880000004C899590000000F20F1185C0000000F20F118DC8000000F20F1195D0000000F20F119DD8000000F20F11A5E0000000F20F11ADE8000000F20F11B5F0000000F20F11BDF8000000F2440F118500010000F2440F118D08010000F2440F119510010000F2440F119D18010000F2440F11A520010000F2440F11AD28010000F2440F11B530010000488B7C240849BB101CD1CC9902000041FFD3488B442408F6400480488B4558488B4D60488B5568488B7570488B7D784C8B85800000004C8B8D880000004C8B9590000000F20F1085C0000000F20F108DC8000000F20F1095D0000000F20F109DD8000000F20F10A5E0000000F20F10ADE8000000F20F10B5F0000000F20F10BDF8000000F2440F108500010000F2440F108D08010000F2440F109510010000F2440F109D18010000F2440F10A520010000F2440F10AD28010000F2440F10B530010000C20800 +[d4bd45f09fc] jit-backend-dump} +[d4bd45f4d26] {jit-backend-dump BACKEND x86_64 -SYS_EXECUTABLE python -CODE_DUMP @7fe7c97fa988 +0 488B042508E6150348C7042500E615030000000048C7042508E61503000000004889453848C7451000C2B5014889E84C8BBC24880000004C8BB424800000004C8B6C24784C8B642470488B5C2468488B6C24604881C498000000C3 -[19c473e625e0] jit-backend-dump} -[19c473e68362] {jit-backend-dump +SYS_EXECUTABLE pypy +CODE_DUMP @29dd4436a33 +0 49BB48D3E5CE99020000498B0349BB40D3E5CE9902000049C7030000000049BB48D3E5CE9902000049C703000000004889453849BBE00A61CD990200004C895D104889E848BB30CF61CD9902000048832B084C8BBC24880000004C8BB424800000004C8B6C24784C8B642470488B5C2468488B6C24604881C498000000C3 +[d4bd45fbd0a] jit-backend-dump} +[d4bd46054f0] {jit-backend-dump BACKEND x86_64 -SYS_EXECUTABLE python -CODE_DUMP @7fe7c97fa9e3 +0 48894D584889556848895D70488975784C8985880000004C898D900000004C8995980000004C89A5A00000004C89ADA80000004C89B5B00000004C89BDB8000000F20F1185C0000000F20F118DC8000000F20F1195D0000000F20F119DD8000000F20F11A5E0000000F20F11ADE8000000F20F11B5F0000000F20F11BDF8000000F2440F118500010000F2440F118D08010000F2440F119510010000F2440F119D18010000F2440F11A520010000F2440F11AD28010000F2440F11B530010000488B4C240848894D204829C74883EC0848C745281000000041BBB0A4E80041FFD34883C4084885C00F84F4000000F645040174154883EC0849BBFDA17FC9E77F000041FFD34883C40848C7452800000000488B4D58488B5568488B5D70488B75784C8B85880000004C8B8D900000004C8B95980000004C8BA5A00000004C8BADA80000004C8BB5B00000004C8BBDB8000000F20F1085C0000000F20F108DC8000000F20F1095D0000000F20F109DD8000000F20F10A5E0000000F20F10ADE8000000F20F10B5F0000000F20F10BDF8000000F2440F108500010000F2440F108D08010000F2440F109510010000F2440F109D18010000F2440F10A520010000F2440F10AD28010000F2440F10B530010000488B3C25484CB60148C7452000000000C34883C40849BB88A97FC9E77F000041FFE3 -[19c473e6c488] jit-backend-dump} -[19c473e6ed0e] {jit-backend-dump +SYS_EXECUTABLE pypy +CODE_DUMP @29dd4436ab1 +0 48894D584889556848895D70488975784C8985880000004C898D900000004C8995980000004C89A5A00000004C89ADA80000004C89B5B00000004C89BDB8000000F20F1185C0000000F20F118DC8000000F20F1195D0000000F20F119DD8000000F20F11A5E0000000F20F11ADE8000000F20F11B5F0000000F20F11BDF8000000F2440F118500010000F2440F118D08010000F2440F119510010000F2440F119D18010000F2440F11A520010000F2440F11AD28010000F2440F11B530010000488B4C240848894D204883EC084829C749BB30A39FCC9902000041FFD34883C4084885C00F840201000049BB30CF61CD99020000498B0B488B69F8F645040174154883EC0849BB306243D49D02000041FFD34883C408488B4D58488B5568488B5D70488B75784C8B85880000004C8B8D900000004C8B95980000004C8BA5A00000004C8BADA80000004C8BB5B00000004C8BBDB8000000F20F1085C0000000F20F108DC8000000F20F1095D0000000F20F109DD8000000F20F10A5E0000000F20F10ADE8000000F20F10B5F0000000F20F10BDF8000000F2440F108500010000F2440F108D08010000F2440F109510010000F2440F109D18010000F2440F10A520010000F2440F10AD28010000F2440F10B53001000049BB28CE61CD99020000498B3B48C7452000000000C34883C40849BB336A43D49D02000041FFE3 +[d4bd461836e] jit-backend-dump} +[d4bd461e1f2] {jit-backend-dump BACKEND x86_64 -SYS_EXECUTABLE python -CODE_DUMP @7fe7c97fabd6 +0 4889E74883EC0841BBD00F210141FFD34883C408488B042500E615034885C07501C34883C40849BB88A97FC9E77F000041FFE3 -[19c473e70017] jit-backend-dump} -[19c473e70673] {jit-backend-counts -[19c473e70a42] jit-backend-counts} -[19c47442a7d0] {jit-backend -[19c4746efe37] {jit-backend-dump +SYS_EXECUTABLE pypy +CODE_DUMP @29dd4436cae +0 48894D584889556848895D70488975784C8985880000004C898D900000004C8995980000004C89A5A00000004C89ADA80000004C89B5B00000004C89BDB8000000F20F1185C0000000F20F118DC8000000F20F1195D0000000F20F119DD8000000F20F11A5E0000000F20F11ADE8000000F20F11B5F0000000F20F11BDF8000000F2440F118500010000F2440F118D08010000F2440F119510010000F2440F119D18010000F2440F11A520010000F2440F11AD28010000F2440F11B530010000488B4C240848894D204883EC084889FA4889C6488B7C241849BB40A29FCC9902000041FFD34883C4084885C00F840201000049BB30CF61CD99020000498B0B488B69F8F645040174154883EC0849BB306243D49D02000041FFD34883C408488B4D58488B5568488B5D70488B75784C8B85880000004C8B8D900000004C8B95980000004C8BA5A00000004C8BADA80000004C8BB5B00000004C8BBDB8000000F20F1085C0000000F20F108DC8000000F20F1095D0000000F20F109DD8000000F20F10A5E0000000F20F10ADE8000000F20F10B5F0000000F20F10BDF8000000F2440F108500010000F2440F108D08010000F2440F109510010000F2440F109D18010000F2440F10A520010000F2440F10AD28010000F2440F10B53001000049BB28CE61CD99020000498B3B48C7452000000000C34883C40849BB336A43D49D02000041FFE3 +[d4bd4636ab0] jit-backend-dump} +[d4bd46401ae] {jit-backend-dump BACKEND x86_64 -SYS_EXECUTABLE python -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 +SYS_EXECUTABLE pypy +CODE_DUMP @29dd4436eb3 +0 48894D584889556848895D70488975784C8985880000004C898D900000004C8995980000004C89A5A00000004C89ADA80000004C89B5B00000004C89BDB8000000F20F1185C0000000F20F118DC8000000F20F1195D0000000F20F119DD8000000F20F11A5E0000000F20F11ADE8000000F20F11B5F0000000F20F11BDF8000000F2440F118500010000F2440F118D08010000F2440F119510010000F2440F119D18010000F2440F11A520010000F2440F11AD28010000F2440F11B530010000488B4C240848894D204883EC0849BB00A39FCC9902000041FFD34883C4084885C00F840201000049BB30CF61CD99020000498B0B488B69F8F645040174154883EC0849BB306243D49D02000041FFD34883C408488B4D58488B5568488B5D70488B75784C8B85880000004C8B8D900000004C8B95980000004C8BA5A00000004C8BADA80000004C8BB5B00000004C8BBDB8000000F20F1085C0000000F20F108DC8000000F20F1095D0000000F20F109DD8000000F20F10A5E0000000F20F10ADE8000000F20F10B5F0000000F20F10BDF8000000F2440F108500010000F2440F108D08010000F2440F109510010000F2440F109D18010000F2440F10A520010000F2440F10AD28010000F2440F10B53001000049BB28CE61CD99020000498B3B48C7452000000000C34883C40849BB336A43D49D02000041FFE3 +[d4bd4653aa0] jit-backend-dump} +[d4bd465898a] {jit-backend-dump BACKEND x86_64 -SYS_EXECUTABLE python -CODE_DUMP @7fe7c97fadd6 +0 A1000000 -[19c474709e17] jit-backend-dump} -[19c47470a414] {jit-backend-dump +SYS_EXECUTABLE pypy +CODE_DUMP @29dd44370ad +0 48894D584889556848895D70488975784C8985880000004C898D900000004C8995980000004C89A5A00000004C89ADA80000004C89B5B00000004C89BDB8000000F20F1185C0000000F20F118DC8000000F20F1195D0000000F20F119DD8000000F20F11A5E0000000F20F11ADE8000000F20F11B5F0000000F20F11BDF8000000F2440F118500010000F2440F118D08010000F2440F119510010000F2440F119D18010000F2440F11A520010000F2440F11AD28010000F2440F11B530010000488B4C240848894D204883EC0849BBD0A29FCC9902000041FFD34883C4084885C00F840201000049BB30CF61CD99020000498B0B488B69F8F645040174154883EC0849BB306243D49D02000041FFD34883C408488B4D58488B5568488B5D70488B75784C8B85880000004C8B8D900000004C8B95980000004C8BA5A00000004C8BADA80000004C8BB5B00000004C8BBDB8000000F20F1085C0000000F20F108DC8000000F20F1095D0000000F20F109DD8000000F20F10A5E0000000F20F10ADE8000000F20F10B5F0000000F20F10BDF8000000F2440F108500010000F2440F108D08010000F2440F109510010000F2440F109D18010000F2440F10A520010000F2440F10AD28010000F2440F10B53001000049BB28CE61CD99020000498B3B48C7452000000000C34883C40849BB336A43D49D02000041FFE3 +[d4bd466b5ba] jit-backend-dump} +[d4bd466f11c] {jit-backend-dump BACKEND x86_64 -SYS_EXECUTABLE python -CODE_DUMP @7fe7c97fade8 +0 B4000000 -[19c47470ae2a] jit-backend-dump} -[19c47470b293] {jit-backend-dump +SYS_EXECUTABLE pypy +CODE_DUMP @29dd44372a7 +0 4889E74883EC0849BB40CEE3CC9902000041FFD34883C40849BB40D3E5CE99020000498B034885C07501C34883C40849BB336A43D49D02000041FFE3 +[d4bd4673ed6] jit-backend-dump} +[d4bd4674e24] {jit-backend-counts +[d4bd4675ab2] jit-backend-counts} +[d4bd590ac7a] {jit-backend +[d4bd5fccb60] {jit-backend-dump BACKEND x86_64 -SYS_EXECUTABLE python -CODE_DUMP @7fe7c97fadf2 +0 CF000000 -[19c47470bc50] jit-backend-dump} -[19c47470c075] {jit-backend-dump +SYS_EXECUTABLE pypy +CODE_DUMP @29dd4437450 +0 4881EC9800000048896C24604889FD48895C24684C896424704C896C24784C89B424800000004C89BC248800000049BB30CF61CD99020000498B1B48892B4883C30849891B49BB1867E6CE99020000498B034829E049BBE0E6ACCE99020000493B03760D49BBA77243D49D02000041FFD349BBD8401FD29D0200004D8B3B4D8D770149BBD8401FD29D0200004D89334C8BB5380100004D8B7E704D8B6E604D8B66784D8B96800000004D8B4E504D0FB6868E000000498B7E58498B7668488B5E10488B5618488B4620488B4E284C8995480100004C8B563048899D50010000488B5E3848898558010000488B46404C8995600100004C8B564848898568010000488B465048898570010000488B465848898578010000488B466048898580010000488B466848898588010000488B46704C8B76784C89B5900100004C8BB6800000004C89B5980100004C8BB6880000004C898DA00100004C8B8E9000000048898DA8010000488B8E9800000048898DB0010000488B8EA000000048898DB8010000488B8EA800000048898DC0010000488B8EB000000048898DC8010000488B8EB800000048898DD0010000488B8EC00000004C89ADD80100004C8BAEC80000004889BDE0010000488995E801000048899DF0010000488985F80100004C89B5000200004C898D0802000048898D100200004C89AD1802000049BBF0401FD29D0200004D8B2B498D4D0149BBF0401FD29D02000049890B4983FC0F0F85000000004C8BA59801000041813C2430EB00000F8500000000498B4C24104885C90F84000000004D8B6C24084C8B491041813990EA03000F85000000004C8B4908498B49084939CD0F8300000000498B49104E8B74E910498D4D0149894C24084983F8000F85000000004983FE000F85000000004C8B85780100004983F8017207418138902300000F85000000004D8B68084983FD000F85000000004983FA01720741813A902300000F850000000049BB0888C4D09D0200004D39DF0F85000000004D8B7A084983C7010F800000000049BBC066E6CE990200004D8B134983FA000F8C000000004C89B5E001000049BB08411FD29D0200004D8B334D8D460149BB08411FD29D0200004D89034D8B41084C39C10F83000000004D8B41104D8B74C8104C8D41014D894424084983FE000F85000000004C89F94983C7010F800000000049BBC066E6CE99020000498B0B4883F9000F8C000000004C89B5E00100004C89C1E986FFFFFF49BB1897C8D09D020000415349BB207343D49D020000415349BB006043D49D02000041FFE349BBF06254D39D020000415349BB307343D49D020000415349BB006043D49D02000041FFE349BB786254D39D020000415349BB407343D49D020000415349BB006043D49D02000041FFE349BB006254D39D020000415349BB507343D49D020000415349BB006043D49D02000041FFE349BB886154D39D020000415349BB607343D49D020000415349BB006043D49D02000041FFE349BB106154D39D020000415349BB707343D49D020000415349BB006043D49D02000041FFE349BB986054D39D020000415349BB807343D49D020000415349BB006043D49D02000041FFE349BB206054D39D020000415349BB907343D49D020000415349BB006043D49D02000041FFE349BB889FC8D09D020000415349BBA07343D49D020000415349BB006043D49D02000041FFE349BB109FC8D09D020000415349BBB07343D49D020000415349BB006043D49D02000041FFE349BB989EC8D09D020000415349BBC07343D49D020000415349BB006043D49D02000041FFE349BB209EC8D09D020000415349BBD07343D49D020000415349BB006043D49D02000041FFE349BBA89DC8D09D020000415349BBE07343D49D020000415349BB006043D49D02000041FFE349BB309DC8D09D020000415349BBF07343D49D020000415349BB006043D49D02000041FFE349BBB89CC8D09D020000415349BB007443D49D020000415349BB006043D49D02000041FFE349BB409CC8D09D020000415349BB107443D49D020000415349BB006043D49D02000041FFE349BBC89BC8D09D020000415349BB207443D49D020000415349BB006043D49D02000041FFE349BB509BC8D09D020000415349BB307443D49D020000415349BB006043D49D02000041FFE349BBD89AC8D09D020000415349BB407443D49D020000415349BB006043D49D02000041FFE3 +[d4bd6011706] jit-backend-dump} +[d4bd6013120] {jit-backend-addr +Loop 0 ( #274 FOR_ITER) has address 0x29dd44374c1 to 0x29dd44377d4 (bootstrap 0x29dd4437450) +[d4bd6016fb0] jit-backend-addr} +[d4bd6018af2] {jit-backend-dump BACKEND x86_64 -SYS_EXECUTABLE python -CODE_DUMP @7fe7c97fae05 +0 E1000000 -[19c47470c9b8] jit-backend-dump} -[19c47470cdc2] {jit-backend-dump +SYS_EXECUTABLE pypy +CODE_DUMP @29dd443766c +0 64010000 +[d4bd601be22] jit-backend-dump} +[d4bd601cec0] {jit-backend-dump BACKEND x86_64 -SYS_EXECUTABLE python -CODE_DUMP @7fe7c97fae16 +0 F5000000 -[19c47470d695] jit-backend-dump} -[19c47470dc77] {jit-backend-dump +SYS_EXECUTABLE pypy +CODE_DUMP @29dd4437681 +0 74010000 +[d4bd601f6c4] jit-backend-dump} +[d4bd602088a] {jit-backend-dump BACKEND x86_64 -SYS_EXECUTABLE python -CODE_DUMP @7fe7c97fae2d +0 28010000 -[19c47470e564] jit-backend-dump} -[19c47470e995] {jit-backend-dump +SYS_EXECUTABLE pypy +CODE_DUMP @29dd443768f +0 8B010000 +[d4bd60230cc] jit-backend-dump} +[d4bd6024280] {jit-backend-dump BACKEND x86_64 -SYS_EXECUTABLE python -CODE_DUMP @7fe7c97fae59 +0 21010000 -[19c47470f2a6] jit-backend-dump} -[19c47470f74a] {jit-backend-dump +SYS_EXECUTABLE pypy +CODE_DUMP @29dd44376a5 +0 9A010000 +[d4bd6026e72] jit-backend-dump} +[d4bd6027d12] {jit-backend-dump BACKEND x86_64 -SYS_EXECUTABLE python -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 +SYS_EXECUTABLE pypy +CODE_DUMP @29dd44376b6 +0 AE010000 +[d4bd602b122] jit-backend-dump} +[d4bd602c1f6] {jit-backend-dump +BACKEND x86_64 +SYS_EXECUTABLE pypy +CODE_DUMP @29dd44376d2 +0 B7010000 +[d4bd602eac2] jit-backend-dump} +[d4bd602fa20] {jit-backend-dump +BACKEND x86_64 +SYS_EXECUTABLE pypy +CODE_DUMP @29dd44376dc +0 D2010000 +[d4bd603223e] jit-backend-dump} +[d4bd6033028] {jit-backend-dump +BACKEND x86_64 +SYS_EXECUTABLE pypy +CODE_DUMP @29dd44376f6 +0 DD010000 +[d4bd607b458] jit-backend-dump} +[d4bd607c918] {jit-backend-dump +BACKEND x86_64 +SYS_EXECUTABLE pypy +CODE_DUMP @29dd4437704 +0 F4010000 +[d4bd607f10c] jit-backend-dump} +[d4bd607ffd6] {jit-backend-dump +BACKEND x86_64 +SYS_EXECUTABLE pypy +CODE_DUMP @29dd4437717 +0 06020000 +[d4bd6082502] jit-backend-dump} +[d4bd608348c] {jit-backend-dump +BACKEND x86_64 +SYS_EXECUTABLE pypy +CODE_DUMP @29dd443772a +0 18020000 +[d4bd6085a92] jit-backend-dump} +[d4bd6086a94] {jit-backend-dump +BACKEND x86_64 +SYS_EXECUTABLE pypy +CODE_DUMP @29dd4437738 +0 2F020000 +[d4bd6089206] jit-backend-dump} +[d4bd608ab60] {jit-backend-dump +BACKEND x86_64 +SYS_EXECUTABLE pypy +CODE_DUMP @29dd443774f +0 62020000 +[d4bd608d342] jit-backend-dump} +[d4bd608e20e] {jit-backend-dump +BACKEND x86_64 +SYS_EXECUTABLE pypy +CODE_DUMP @29dd4437781 +0 55020000 +[d4bd6090ab6] jit-backend-dump} +[d4bd6091944] {jit-backend-dump +BACKEND x86_64 +SYS_EXECUTABLE pypy +CODE_DUMP @29dd443779d +0 5E020000 +[d4bd6093f98] jit-backend-dump} +[d4bd6094d3c] {jit-backend-dump +BACKEND x86_64 +SYS_EXECUTABLE pypy +CODE_DUMP @29dd44377aa +0 76020000 +[d4bd609738e] jit-backend-dump} +[d4bd6098392] {jit-backend-dump +BACKEND x86_64 +SYS_EXECUTABLE pypy +CODE_DUMP @29dd44377c1 +0 A9020000 +[d4bd609ab48] jit-backend-dump} +[d4bd609d80a] jit-backend} +[d4bd60a2c66] {jit-log-opt-loop +# Loop 0 ( #274 FOR_ITER) : loop with 106 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: p16 = getfield_gc(p0, descr=) -+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] -debug_merge_point(0, 0, ' #12 LOAD_CONST') -+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] -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') -debug_merge_point(0, 0, ' #27 INPLACE_ADD') -+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(51804288, descr=) -+327: i29 = int_lt(i27, 0) -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(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] -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') -debug_merge_point(0, 0, ' #27 INPLACE_ADD') -+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(51804288, descr=) -+393: i34 = int_lt(i33, 0) -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(140633495988056)) -+411: --end of the loop-- -[19c4747929e2] jit-log-opt-loop} -[19c474a8bcae] {jit-backend -[19c474b8b379] {jit-backend-dump ++143: p2 = getfield_gc(p0, descr=) ++154: p3 = getfield_gc(p0, descr=) ++158: i4 = getfield_gc(p0, descr=) ++162: p5 = getfield_gc(p0, descr=) ++169: p6 = getfield_gc(p0, descr=) ++173: i7 = getfield_gc(p0, descr=) ++181: i8 = getfield_gc(p0, descr=) ++185: p9 = getfield_gc(p0, descr=) ++189: p11 = getarrayitem_gc(p9, 0, descr=) ++193: p13 = getarrayitem_gc(p9, 1, descr=) ++197: p15 = getarrayitem_gc(p9, 2, descr=) ++201: p17 = getarrayitem_gc(p9, 3, descr=) ++205: p19 = getarrayitem_gc(p9, 4, descr=) ++216: p21 = getarrayitem_gc(p9, 5, descr=) ++227: p23 = getarrayitem_gc(p9, 6, descr=) ++238: p25 = getarrayitem_gc(p9, 7, descr=) ++249: p27 = getarrayitem_gc(p9, 8, descr=) ++260: p29 = getarrayitem_gc(p9, 9, descr=) ++271: p31 = getarrayitem_gc(p9, 10, descr=) ++282: p33 = getarrayitem_gc(p9, 11, descr=) ++293: p35 = getarrayitem_gc(p9, 12, descr=) ++304: p37 = getarrayitem_gc(p9, 13, descr=) ++308: p39 = getarrayitem_gc(p9, 14, descr=) ++322: p41 = getarrayitem_gc(p9, 15, descr=) ++336: p43 = getarrayitem_gc(p9, 16, descr=) ++350: p45 = getarrayitem_gc(p9, 17, descr=) ++364: p47 = getarrayitem_gc(p9, 18, descr=) ++378: p49 = getarrayitem_gc(p9, 19, descr=) ++392: p51 = getarrayitem_gc(p9, 20, descr=) ++406: p53 = getarrayitem_gc(p9, 21, descr=) ++420: p55 = getarrayitem_gc(p9, 22, descr=) ++434: p57 = getarrayitem_gc(p9, 23, descr=) ++448: p58 = getfield_gc(p0, descr=) ++448: label(p0, p1, p2, p3, i4, p5, p6, i7, i8, p11, p13, p15, p17, p19, p21, p23, p25, p27, p29, p31, p33, p35, p37, p39, p41, p43, p45, p47, p49, p51, p53, p55, p57, descr=TargetToken(2876835872976)) +debug_merge_point(0, 0, ' #274 FOR_ITER') ++534: guard_value(i4, 15, descr=) [i4, p1, p0, p2, p3, p5, p6, i7, i8, p11, p13, p15, p17, p19, p21, p23, p25, p27, p29, p31, p33, p35, p37, p39, p41, p43, p45, p47, p49, p51, p53, p55, p57] ++544: guard_class(p39, 2859595984528, descr=) [p1, p0, p39, p2, p3, p5, p6, i7, p11, p13, p15, p17, p19, p21, p23, p25, p27, p29, p31, p33, p35, p37, p41, p43, p45, p47, p49, p51, p53, p55, p57] ++565: p61 = getfield_gc(p39, descr=) ++570: guard_nonnull(p61, descr=) [p1, p0, p39, p61, p2, p3, p5, p6, i7, p11, p13, p15, p17, p19, p21, p23, p25, p27, p29, p31, p33, p35, p37, p41, p43, p45, p47, p49, p51, p53, p55, p57] ++579: i62 = getfield_gc(p39, descr=) ++584: p63 = getfield_gc(p61, descr=) ++588: guard_class(p63, 2859596180976, descr=) [p1, p0, p39, i62, p63, p61, p2, p3, p5, p6, i7, p11, p13, p15, p17, p19, p21, p23, p25, p27, p29, p31, p33, p35, p37, p41, p43, p45, p47, p49, p51, p53, p55, p57] ++601: p65 = getfield_gc(p61, descr=) ++605: i66 = getfield_gc(p65, descr=) ++609: i67 = uint_ge(i62, i66) +guard_false(i67, descr=) [p1, p0, p39, i62, i66, p65, p2, p3, p5, p6, i7, p11, p13, p15, p17, p19, p21, p23, p25, p27, p29, p31, p33, p35, p37, p41, p43, p45, p47, p49, p51, p53, p55, p57] ++618: p68 = getfield_gc(p65, descr=) ++622: i69 = getarrayitem_gc(p68, i62, descr=) ++627: i71 = int_add(i62, 1) ++631: setfield_gc(p39, i71, descr=) ++636: guard_value(i7, 0, descr=) [i7, p1, p0, p2, p3, p5, p6, p11, p13, p15, p17, p19, p21, p23, p25, p27, p29, p31, p33, p35, p37, p39, p43, p45, p47, p49, p51, p53, p55, p57, i69] +debug_merge_point(0, 0, ' #277 STORE_FAST') +debug_merge_point(0, 0, ' #280 LOAD_FAST') +debug_merge_point(0, 0, ' #283 POP_JUMP_IF_FALSE') ++646: i73 = int_is_true(i69) +guard_false(i73, descr=) [p1, p0, p2, p3, p5, p6, p11, p13, p15, p17, p19, p21, p23, p25, p27, p29, p31, p33, p37, p39, p43, p45, p47, p49, p51, p53, p55, p57, i69] +debug_merge_point(0, 0, ' #320 LOAD_FAST') ++656: guard_nonnull_class(p29, ConstClass(W_IntObject), descr=) [p1, p0, p29, p2, p3, p5, p6, p11, p13, p15, p17, p19, p21, p23, p25, p27, p31, p33, p37, p39, p43, p45, p47, p49, p51, p53, p55, p57, i69] +debug_merge_point(0, 0, ' #323 POP_JUMP_IF_FALSE') ++682: i75 = getfield_gc_pure(p29, descr=) ++686: i76 = int_is_true(i75) +guard_false(i76, descr=) [p1, p0, p29, p2, p3, p5, p6, p11, p13, p15, p17, p19, p21, p23, p25, p27, p31, p33, p37, p39, p43, p45, p47, p49, p51, p53, p55, p57, i69] +debug_merge_point(0, 0, ' #351 LOAD_FAST') ++696: guard_nonnull_class(p25, ConstClass(W_IntObject), descr=) [p1, p0, p25, p2, p3, p5, p6, p11, p13, p15, p17, p19, p21, p23, p27, p29, p31, p33, p37, p39, p43, p45, p47, p49, p51, p53, p55, p57, i69] +debug_merge_point(0, 0, ' #354 LOAD_CONST') ++715: guard_value(p2, ConstPtr(ptr78), descr=) [p1, p0, p2, p3, p5, p6, p11, p13, p15, p17, p19, p21, p23, p25, p27, p29, p31, p33, p37, p39, p43, p45, p47, p49, p51, p53, p55, p57, i69] +debug_merge_point(0, 0, ' #357 BINARY_ADD') ++734: i79 = getfield_gc_pure(p25, descr=) ++738: i81 = int_add_ovf(i79, 1) +guard_no_overflow(descr=) [p1, p0, p25, i81, p3, p5, p6, p11, p13, p15, p17, p19, p21, p23, p27, p29, p31, p33, p37, p39, p45, p47, p49, p51, p53, p55, p57, i69] +debug_merge_point(0, 0, ' #358 STORE_FAST') +debug_merge_point(0, 0, ' #361 JUMP_ABSOLUTE') ++748: guard_not_invalidated(descr=) [p1, p0, p3, p5, p6, p11, p13, p15, p17, p19, p21, p23, p27, p29, p31, p33, p37, p39, p45, p47, p49, p51, p53, p55, p57, i81, i69] ++748: i83 = getfield_raw(2859624457920, descr=) ++761: i85 = int_lt(i83, 0) +guard_false(i85, descr=) [p1, p0, p3, p5, p6, p11, p13, p15, p17, p19, p21, p23, p27, p29, p31, p33, p37, p39, p45, p47, p49, p51, p53, p55, p57, i81, i69] +debug_merge_point(0, 0, ' #274 FOR_ITER') ++771: label(p0, p1, p3, p5, p6, p11, p13, p15, p17, p19, p21, p23, i81, p27, p29, p31, p33, i69, p37, p39, p45, p47, p49, p51, p53, p55, p57, p65, i71, descr=TargetToken(2876835873064)) +debug_merge_point(0, 0, ' #274 FOR_ITER') ++808: i86 = getfield_gc(p65, descr=) ++812: i87 = uint_ge(i71, i86) +guard_false(i87, descr=) [p1, p0, p39, i71, i86, p65, p3, p5, p6, p11, p13, p15, p17, p19, p21, p23, p27, p29, p31, p33, p37, p45, p47, p49, p51, p53, p55, p57, i81, i69] ++821: p88 = getfield_gc(p65, descr=) ++825: i89 = getarrayitem_gc(p88, i71, descr=) ++830: i90 = int_add(i71, 1) +debug_merge_point(0, 0, ' #277 STORE_FAST') +debug_merge_point(0, 0, ' #280 LOAD_FAST') +debug_merge_point(0, 0, ' #283 POP_JUMP_IF_FALSE') ++834: setfield_gc(p39, i90, descr=) ++839: i91 = int_is_true(i89) +guard_false(i91, descr=) [p1, p0, p3, p5, p6, p11, p13, p15, p17, p19, p21, p23, p27, p29, p31, p33, p37, p39, p45, p47, p49, p51, p53, p55, p57, i89, i81, None] +debug_merge_point(0, 0, ' #320 LOAD_FAST') +debug_merge_point(0, 0, ' #323 POP_JUMP_IF_FALSE') +debug_merge_point(0, 0, ' #351 LOAD_FAST') +debug_merge_point(0, 0, ' #354 LOAD_CONST') +debug_merge_point(0, 0, ' #357 BINARY_ADD') ++849: i93 = int_add_ovf(i81, 1) +guard_no_overflow(descr=) [p1, p0, i93, p3, p5, p6, p11, p13, p15, p17, p19, p21, p23, p27, p29, p31, p33, p37, p39, p45, p47, p49, p51, p53, p55, p57, i89, i81, None] +debug_merge_point(0, 0, ' #358 STORE_FAST') +debug_merge_point(0, 0, ' #361 JUMP_ABSOLUTE') ++862: guard_not_invalidated(descr=) [p1, p0, p3, p5, p6, p11, p13, p15, p17, p19, p21, p23, p27, p29, p31, p33, p37, p39, p45, p47, p49, p51, p53, p55, p57, i93, i89, None, None] ++862: i94 = getfield_raw(2859624457920, descr=) ++875: i95 = int_lt(i94, 0) +guard_false(i95, descr=) [p1, p0, p3, p5, p6, p11, p13, p15, p17, p19, p21, p23, p27, p29, p31, p33, p37, p39, p45, p47, p49, p51, p53, p55, p57, i93, i89, None, None] +debug_merge_point(0, 0, ' #274 FOR_ITER') ++885: jump(p0, p1, p3, p5, p6, p11, p13, p15, p17, p19, p21, p23, i93, p27, p29, p31, p33, i89, p37, p39, p45, p47, p49, p51, p53, p55, p57, p65, i90, descr=TargetToken(2876835873064)) ++900: --end of the loop-- +[d4bd632bb1a] jit-log-opt-loop} +[d4bd75888aa] {jit-backend +[d4bd786b446] {jit-backend-dump BACKEND x86_64 -SYS_EXECUTABLE python -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 +SYS_EXECUTABLE pypy +CODE_DUMP @29dd4437bc8 +0 48817D50FFFFFF007D2448C7442408FFFFFF0049BB987A43D49D0200004C891C2449BBCA6243D49D02000041FFD349BBC0401FD29D0200004D8B2B4D8D4D0149BBC0401FD29D0200004D890B4C8B8D780100004983F9017207418139902300000F850000000049BB0888C4D09D0200004D39DF0F85000000004D8B79084983FF000F84000000004983C7010F80000000004983FA01720741813A902300000F85000000004D8B4A084983C1010F800000000049BBC066E6CE990200004D8B134983FA000F8C000000004C89B57801000049BB20411FD29D0200004D8B334D8D560149BB20411FD29D0200004D891341813C2430EB00000F85000000004D8B5424104D85D20F84000000004D8B7424084D8B6A1041817D0090EA03000F85000000004D8B6A084D8B55084D39D60F83000000004D8B55104F8B6CF2104D8D56014D895424084983FD000F84000000004983FF000F84000000004D89FA4983C7010F80000000004D89CA4983C1010F800000000049BBC066E6CE990200004D8B134983FA000F8C000000004C89AD78010000E93BFFFFFF49BB306E54D39D020000415349BBA87A43D49D020000415349BB006043D49D02000041FFE349BB907754D39D020000415349BBB87A43D49D020000415349BB006043D49D02000041FFE349BB187754D39D020000415349BBC87A43D49D020000415349BB006043D49D02000041FFE349BBA07654D39D020000415349BBD87A43D49D020000415349BB006043D49D02000041FFE349BB287654D39D020000415349BBE87A43D49D020000415349BB006043D49D02000041FFE349BBB07554D39D020000415349BBF87A43D49D020000415349BB006043D49D02000041FFE349BB387554D39D020000415349BB087B43D49D020000415349BB006043D49D02000041FFE349BBC07454D39D020000415349BB187B43D49D020000415349BB006043D49D02000041FFE349BB487454D39D020000415349BB287B43D49D020000415349BB006043D49D02000041FFE349BBD07354D39D020000415349BB387B43D49D020000415349BB006043D49D02000041FFE349BB587354D39D020000415349BB487B43D49D020000415349BB006043D49D02000041FFE349BBE07254D39D020000415349BB587B43D49D020000415349BB006043D49D02000041FFE349BB687254D39D020000415349BB687B43D49D020000415349BB006043D49D02000041FFE349BBF07154D39D020000415349BB787B43D49D020000415349BB006043D49D02000041FFE349BB787154D39D020000415349BB887B43D49D020000415349BB006043D49D02000041FFE349BB007154D39D020000415349BB987B43D49D020000415349BB006043D49D02000041FFE349BB887054D39D020000415349BBA87B43D49D020000415349BB006043D49D02000041FFE349BB107054D39D020000415349BBB87B43D49D020000415349BB006043D49D02000041FFE3 +[d4bd78951be] jit-backend-dump} +[d4bd7897294] {jit-backend-dump BACKEND x86_64 -SYS_EXECUTABLE python -CODE_DUMP @7fe7c97fb1f6 +0 31010000 -[19c474ba1e7c] jit-backend-dump} -[19c474ba2395] {jit-backend-dump +SYS_EXECUTABLE pypy +CODE_DUMP @29dd4437bcc +0 39000000 +[d4bd789a7de] jit-backend-dump} +[d4bd789b93c] {jit-backend-dump BACKEND x86_64 -SYS_EXECUTABLE python -CODE_DUMP @7fe7c97fb208 +0 44010000 -[19c474ba2cfc] jit-backend-dump} -[19c474ba314d] {jit-backend-dump +SYS_EXECUTABLE pypy +CODE_DUMP @29dd4437bd7 +0 39000000 +[d4bd789e688] jit-backend-dump} +[d4bd789f6be] {jit-backend-addr +bridge out of Guard 0x29dd3546098 has address 0x29dd4437bc8 to 0x29dd4437d5d +[d4bd78a1f78] jit-backend-addr} +[d4bd78a3324] {jit-backend-dump BACKEND x86_64 -SYS_EXECUTABLE python -CODE_DUMP @7fe7c97fb212 +0 5F010000 -[19c474ba3a2b] jit-backend-dump} -[19c474ba3e5f] {jit-backend-dump +SYS_EXECUTABLE pypy +CODE_DUMP @29dd4437c2a +0 2F010000 +[d4bd78a62e8] jit-backend-dump} +[d4bd78a719a] {jit-backend-dump BACKEND x86_64 -SYS_EXECUTABLE python -CODE_DUMP @7fe7c97fb225 +0 71010000 -[19c474ba4793] jit-backend-dump} -[19c474ba4bc7] {jit-backend-dump +SYS_EXECUTABLE pypy +CODE_DUMP @29dd4437c3d +0 41010000 +[d4bd78aa178] jit-backend-dump} +[d4bd78ab206] {jit-backend-dump BACKEND x86_64 -SYS_EXECUTABLE python -CODE_DUMP @7fe7c97fb236 +0 85010000 -[19c474ba5566] jit-backend-dump} -[19c474ba59a0] {jit-backend-dump +SYS_EXECUTABLE pypy +CODE_DUMP @29dd4437c4b +0 58010000 +[d4bd78adb80] jit-backend-dump} +[d4bd78aea3a] {jit-backend-dump BACKEND x86_64 -SYS_EXECUTABLE python -CODE_DUMP @7fe7c97fb24d +0 93010000 -[19c474ba62ae] jit-backend-dump} -[19c474ba66e1] {jit-backend-dump +SYS_EXECUTABLE pypy +CODE_DUMP @29dd4437c55 +0 73010000 +[d4bd78b15ee] jit-backend-dump} +[d4bd78b2378] {jit-backend-dump BACKEND x86_64 -SYS_EXECUTABLE python -CODE_DUMP @7fe7c97fb264 +0 A1010000 -[19c474ba6f81] jit-backend-dump} -[19c474ba7727] {jit-backend-dump +SYS_EXECUTABLE pypy +CODE_DUMP @29dd4437c68 +0 85010000 +[d4bd78d5c42] jit-backend-dump} +[d4bd78d6e8a] {jit-backend-dump BACKEND x86_64 -SYS_EXECUTABLE python -CODE_DUMP @7fe7c97fb2b8 +0 97010000 -[19c474ba801d] jit-backend-dump} -[19c474ba844b] {jit-backend-dump +SYS_EXECUTABLE pypy +CODE_DUMP @29dd4437c76 +0 9C010000 +[d4bd78d9522] jit-backend-dump} +[d4bd78daa16] {jit-backend-dump BACKEND x86_64 -SYS_EXECUTABLE python -CODE_DUMP @7fe7c97fb2c6 +0 AE010000 -[19c474ba8d0e] jit-backend-dump} -[19c474ba91df] {jit-backend-dump +SYS_EXECUTABLE pypy +CODE_DUMP @29dd4437c8d +0 CF010000 +[d4bd78dd08c] jit-backend-dump} +[d4bd78de098] {jit-backend-dump BACKEND x86_64 -SYS_EXECUTABLE python -CODE_DUMP @7fe7c97fb2dd +0 E1010000 -[19c474ba9a8b] jit-backend-dump} -[19c474ba9ece] {jit-backend-dump +SYS_EXECUTABLE pypy +CODE_DUMP @29dd4437cc0 +0 C1010000 +[d4bd78e08ea] jit-backend-dump} +[d4bd78e195e] {jit-backend-dump BACKEND x86_64 -SYS_EXECUTABLE python -CODE_DUMP @7fe7c97fb309 +0 DA010000 -[19c474baa811] jit-backend-dump} -[19c474baac68] {jit-backend-dump +SYS_EXECUTABLE pypy +CODE_DUMP @29dd4437cce +0 D8010000 +[d4bd78e4102] jit-backend-dump} +[d4bd78e4f9a] {jit-backend-dump BACKEND x86_64 -SYS_EXECUTABLE python -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 +SYS_EXECUTABLE pypy +CODE_DUMP @29dd4437ce5 +0 E6010000 +[d4bd78e791a] jit-backend-dump} +[d4bd78e87b2] {jit-backend-dump +BACKEND x86_64 +SYS_EXECUTABLE pypy +CODE_DUMP @29dd4437cf6 +0 FA010000 +[d4bd78eae38] jit-backend-dump} +[d4bd78ebc12] {jit-backend-dump +BACKEND x86_64 +SYS_EXECUTABLE pypy +CODE_DUMP @29dd4437d12 +0 03020000 +[d4bd78ee1fc] jit-backend-dump} +[d4bd78eef7e] {jit-backend-dump +BACKEND x86_64 +SYS_EXECUTABLE pypy +CODE_DUMP @29dd4437d1c +0 1E020000 +[d4bd78f151a] jit-backend-dump} +[d4bd78f234a] {jit-backend-dump +BACKEND x86_64 +SYS_EXECUTABLE pypy +CODE_DUMP @29dd4437d29 +0 36020000 +[d4bd78f4830] jit-backend-dump} +[d4bd78f5634] {jit-backend-dump +BACKEND x86_64 +SYS_EXECUTABLE pypy +CODE_DUMP @29dd4437d36 +0 4E020000 +[d4bd78fc806] jit-backend-dump} +[d4bd78fd812] {jit-backend-dump +BACKEND x86_64 +SYS_EXECUTABLE pypy +CODE_DUMP @29dd4437d4d +0 81020000 +[d4bd78ffeb2] jit-backend-dump} +[d4bd79011dc] {jit-backend-dump +BACKEND x86_64 +SYS_EXECUTABLE pypy +CODE_DUMP @29dd44376dc +0 E8040000 +[d4bd7903838] jit-backend-dump} +[d4bd790546a] jit-backend} +[d4bd7909618] {jit-log-opt-bridge +# bridge out of Guard 0x29dd3546098 with 76 ops +[p0, p1, p2, p3, p4, p5, p6, p7, p8, p9, p10, p11, p12, p13, p14, p15, p16, p17, p18, p19, p20, p21, p22, p23, p24, p25, p26, p27, i28] +debug_merge_point(0, 0, ' #286 LOAD_FAST') ++76: guard_nonnull_class(p15, ConstClass(W_IntObject), descr=) [p0, p1, p15, p2, p3, p4, p5, p6, p7, p8, p9, p10, p11, p12, p13, p14, p16, p17, p18, p19, p20, p21, p22, p23, p24, p25, p26, p27, i28] +debug_merge_point(0, 0, ' #289 LOAD_CONST') ++102: guard_value(p2, ConstPtr(ptr30), descr=) [p0, p1, p2, p3, p4, p5, p6, p7, p8, p9, p10, p11, p12, p13, p14, p15, p16, p17, p18, p19, p20, p21, p22, p23, p24, p25, p26, p27, i28] +debug_merge_point(0, 0, ' #292 COMPARE_OP') ++121: i31 = getfield_gc_pure(p15, descr=) ++125: i33 = int_eq(i31, 0) +guard_false(i33, descr=) [p0, p1, p15, p3, p4, p5, p6, p7, p8, p9, p10, p11, p12, p13, p14, p16, p17, p18, p19, p21, p22, p23, p24, p25, p26, p27, i28] +debug_merge_point(0, 0, ' #295 POP_JUMP_IF_FALSE') +debug_merge_point(0, 0, ' #307 LOAD_FAST') +debug_merge_point(0, 0, ' #310 LOAD_CONST') +debug_merge_point(0, 0, ' #313 BINARY_ADD') ++135: i35 = int_add_ovf(i31, 1) +guard_no_overflow(descr=) [p0, p1, p15, i35, p3, p4, p5, p6, p7, p8, p9, p10, p11, p12, p13, p14, p16, p17, p18, p19, p21, p22, p23, p24, p25, p26, p27, i28] +debug_merge_point(0, 0, ' #314 STORE_FAST') +debug_merge_point(0, 0, ' #317 JUMP_FORWARD') +debug_merge_point(0, 0, ' #351 LOAD_FAST') ++145: guard_nonnull_class(p13, ConstClass(W_IntObject), descr=) [p0, p1, p13, p3, p4, p5, p6, p7, p8, p9, p10, p11, p12, p14, p16, p17, p18, p19, p21, p22, p23, p24, p25, p26, p27, i35, i28] +debug_merge_point(0, 0, ' #354 LOAD_CONST') +debug_merge_point(0, 0, ' #357 BINARY_ADD') ++164: i37 = getfield_gc_pure(p13, descr=) ++168: i39 = int_add_ovf(i37, 1) +guard_no_overflow(descr=) [p0, p1, p13, i39, p3, p4, p5, p6, p7, p8, p9, p10, p11, p12, p14, p16, p17, p18, p19, p21, p22, p23, p24, p25, p26, p27, i35, i28] +debug_merge_point(0, 0, ' #358 STORE_FAST') +debug_merge_point(0, 0, ' #361 JUMP_ABSOLUTE') ++178: guard_not_invalidated(descr=) [p0, p1, p3, p4, p5, p6, p7, p8, p9, p10, p11, p12, p14, p16, p17, p18, p19, p21, p22, p23, p24, p25, p26, p27, i39, i35, i28] ++178: i41 = getfield_raw(2859624457920, descr=) ++191: i43 = int_lt(i41, 0) +guard_false(i43, descr=) [p0, p1, p3, p4, p5, p6, p7, p8, p9, p10, p11, p12, p14, p16, p17, p18, p19, p21, p22, p23, p24, p25, p26, p27, i39, i35, i28] +debug_merge_point(0, 0, ' #274 FOR_ITER') ++201: label(p1, p0, p3, p4, p5, p6, p7, p8, p9, p10, p11, p12, i39, p14, i35, p16, p17, i28, p18, p19, p21, p22, p23, p24, p25, p26, p27, descr=TargetToken(2876835874912)) ++238: guard_class(p19, 2859595984528, descr=) [p0, p1, p19, p3, p4, p5, p6, p7, p8, p9, p10, p11, p12, p14, p16, p17, p18, p21, p22, p23, p24, p25, p26, p27, i35, i28, i39] ++252: p45 = getfield_gc(p19, descr=) ++257: guard_nonnull(p45, descr=) [p0, p1, p19, p45, p3, p4, p5, p6, p7, p8, p9, p10, p11, p12, p14, p16, p17, p18, p21, p22, p23, p24, p25, p26, p27, i35, i28, i39] ++266: i46 = getfield_gc(p19, descr=) ++271: p47 = getfield_gc(p45, descr=) ++275: guard_class(p47, 2859596180976, descr=) [p0, p1, p19, i46, p47, p45, p3, p4, p5, p6, p7, p8, p9, p10, p11, p12, p14, p16, p17, p18, p21, p22, p23, p24, p25, p26, p27, i35, i28, i39] ++289: p49 = getfield_gc(p45, descr=) ++293: i50 = getfield_gc(p49, descr=) ++297: i51 = uint_ge(i46, i50) +guard_false(i51, descr=) [p0, p1, p19, i46, i50, p49, p3, p4, p5, p6, p7, p8, p9, p10, p11, p12, p14, p16, p17, p18, p21, p22, p23, p24, p25, p26, p27, i35, i28, i39] ++306: p52 = getfield_gc(p49, descr=) ++310: i53 = getarrayitem_gc(p52, i46, descr=) ++315: i55 = int_add(i46, 1) +debug_merge_point(0, 0, ' #277 STORE_FAST') +debug_merge_point(0, 0, ' #280 LOAD_FAST') +debug_merge_point(0, 0, ' #283 POP_JUMP_IF_FALSE') ++319: setfield_gc(p19, i55, descr=) ++324: i56 = int_is_true(i53) +guard_true(i56, descr=) [p0, p1, p3, p4, p5, p6, p7, p8, p9, p10, p11, p12, p14, p16, p17, p18, p19, p21, p22, p23, p24, p25, p26, p27, i53, i35, None, i39] +debug_merge_point(0, 0, ' #286 LOAD_FAST') +debug_merge_point(0, 0, ' #289 LOAD_CONST') +debug_merge_point(0, 0, ' #292 COMPARE_OP') ++334: i59 = int_eq(i35, 0) +guard_false(i59, descr=) [p0, p1, p3, p4, p5, p6, p7, p8, p9, p10, p11, p12, p14, p16, p17, p18, p19, p21, p22, p23, p24, p25, p26, p27, i53, i35, None, i39] +debug_merge_point(0, 0, ' #295 POP_JUMP_IF_FALSE') +debug_merge_point(0, 0, ' #307 LOAD_FAST') +debug_merge_point(0, 0, ' #310 LOAD_CONST') +debug_merge_point(0, 0, ' #313 BINARY_ADD') ++344: i61 = int_add_ovf(i35, 1) +guard_no_overflow(descr=) [p0, p1, i61, p3, p4, p5, p6, p7, p8, p9, p10, p11, p12, p14, p16, p17, p18, p19, p21, p22, p23, p24, p25, p26, p27, i53, i35, None, i39] +debug_merge_point(0, 0, ' #314 STORE_FAST') +debug_merge_point(0, 0, ' #317 JUMP_FORWARD') +debug_merge_point(0, 0, ' #351 LOAD_FAST') +debug_merge_point(0, 0, ' #354 LOAD_CONST') +debug_merge_point(0, 0, ' #357 BINARY_ADD') ++357: i63 = int_add_ovf(i39, 1) +guard_no_overflow(descr=) [p0, p1, i63, p3, p4, p5, p6, p7, p8, p9, p10, p11, p12, p14, p16, p17, p18, p19, p21, p22, p23, p24, p25, p26, p27, i61, i53, None, None, i39] +debug_merge_point(0, 0, ' #358 STORE_FAST') +debug_merge_point(0, 0, ' #361 JUMP_ABSOLUTE') ++370: guard_not_invalidated(descr=) [p0, p1, p3, p4, p5, p6, p7, p8, p9, p10, p11, p12, p14, p16, p17, p18, p19, p21, p22, p23, p24, p25, p26, p27, i63, i61, i53, None, None, None] ++370: i65 = getfield_raw(2859624457920, descr=) ++383: i67 = int_lt(i65, 0) +guard_false(i67, descr=) [p0, p1, p3, p4, p5, p6, p7, p8, p9, p10, p11, p12, p14, p16, p17, p18, p19, p21, p22, p23, p24, p25, p26, p27, i63, i61, i53, None, None, None] +debug_merge_point(0, 0, ' #274 FOR_ITER') ++393: jump(p1, p0, p3, p4, p5, p6, p7, p8, p9, p10, p11, p12, i63, p14, i61, p16, p17, i53, p18, p19, p21, p22, p23, p24, p25, p26, p27, descr=TargetToken(2876835874912)) ++405: --end of the loop-- +[d4bd7a0493a] jit-log-opt-bridge} +[d4bd852c8ce] {jit-backend +[d4bd8952728] {jit-backend-dump +BACKEND x86_64 +SYS_EXECUTABLE pypy +CODE_DUMP @29dd4438198 +0 4881EC9800000048896C24604889FD48895C24684C896424704C896C24784C89B424800000004C89BC248800000049BB30CF61CD99020000498B1B48892B4883C30849891B49BB1867E6CE99020000498B034829E049BBE0E6ACCE99020000493B03760D49BBA77243D49D02000041FFD349BB38411FD29D0200004D8B3B4D8D770149BB38411FD29D0200004D89334C8BB5380100004D8B7E704D8B6E604D8B66784D8B96800000004D8B4E504D0FB6868E000000498B7E58498B7668488B5E10488B5618488B4620488B4E2848899D48010000488B5E3048898550010000488B463848898558010000488B46404C89AD600100004C8B6E484C89AD680100004C8B6E504C898D700100004C8B4E5848899578010000488B566048898D80010000488B4E6848898D88010000488B4E7048898D90010000488B4E784C8995980100004889BDA0010000488985A80100004C89ADB00100004C898DB8010000488995C001000048898DC801000049BB50411FD29D020000498B0B488D510149BB50411FD29D0200004989134983FC080F85000000004C8BA56801000041813C2430EB00000F8500000000498B5424104885D20F8400000000498B4C24084C8B4A1041813990EA03000F85000000004C8B4A08498B51084839D10F8300000000498B51104C8B6CCA10488D510149895424084983F8000F85000000004983FD000F85000000004883FB017206813B582800000F85000000004C8B430848899D380100004C89B5A00100004C898DA80100004C89BDB0010000488995B80100004C89C74C89C649BB888043D49D0200004C895D2049BB7026E0CC9902000041FFD349BB30CF61CD99020000498B0B488B69F8F6450401740D49BB306243D49D02000041FFD348C745200000000049BB40D3E5CE9902000049833B000F8500000000488B95B001000049BBC088C4D09D0200004C39DA0F8500000000488B95A00100004C8B7A0849BBF832C3D09D0200004D39DF0F85000000004D8B4F1049BB1033C3D09D0200004D39D90F8500000000488985380100004889C749BBC0EAC4D09D0200004C89DE49BBE88043D49D0200004C895D2049BBE031E0CC9902000041FFD349BB30CF61CD99020000498B0B488B69F8F6450401740D49BB306243D49D02000041FFD348C7452000000000480FB6C04885C00F850000000049BBC066E6CE99020000498B034883F8000F8C000000004C89ADB001000049BB68411FD29D0200004D8B2B498D450149BB68411FD29D020000498903488B85A80100004C8B68084C39ADB80100000F83000000004C8B6810488B95B80100004D8B7CD5104C8D6A01488B95680100004C896A084983FF000F8500000000488BBD38010000488BB53801000049BB388143D49D0200004C895D2049BB7026E0CC9902000041FFD349BB30CF61CD99020000498B0B488B69F8F6450401740D49BB306243D49D02000041FFD348C745200000000049BB40D3E5CE9902000049833B000F8500000000488985380100004889C749BBC0EAC4D09D0200004C89DE49BB688143D49D0200004C895D2049BBE031E0CC9902000041FFD349BB30CF61CD99020000498B0B488B69F8F6450401740D49BB306243D49D02000041FFD348C7452000000000480FB6C04885C00F850000000049BBC066E6CE99020000498B034883F8000F8C000000004C89BDB00100004C89ADB8010000E9A3FEFFFF49BBE04356D39D020000415349BB088043D49D020000415349BB006043D49D02000041FFE349BB405C56D39D020000415349BB188043D49D020000415349BB006043D49D02000041FFE349BBC85B56D39D020000415349BB288043D49D020000415349BB006043D49D02000041FFE349BB505B56D39D020000415349BB388043D49D020000415349BB006043D49D02000041FFE349BBD85A56D39D020000415349BB488043D49D020000415349BB006043D49D02000041FFE349BB605A56D39D020000415349BB588043D49D020000415349BB006043D49D02000041FFE349BBE85956D39D020000415349BB688043D49D020000415349BB006043D49D02000041FFE349BB705956D39D020000415349BB788043D49D020000415349BB006043D49D02000041FFE349BBF85856D39D020000415349BB988043D49D020000415349BB936043D49D02000041FFE349BB805856D39D020000415349BBA88043D49D020000415349BB006043D49D02000041FFE349BB085856D39D020000415349BBB88043D49D020000415349BB006043D49D02000041FFE349BB905756D39D020000415349BBC88043D49D020000415349BB006043D49D02000041FFE349BB185756D39D020000415349BBD88043D49D020000415349BB006043D49D02000041FFE349BBA05656D39D020000415349BBF88043D49D020000415349BB006043D49D02000041FFE349BB285656D39D020000415349BB088143D49D020000415349BB006043D49D02000041FFE349BBB05556D39D020000415349BB188143D49D020000415349BB006043D49D02000041FFE349BB385556D39D020000415349BB288143D49D020000415349BB006043D49D02000041FFE349BBC05456D39D020000415349BB488143D49D020000415349BB936043D49D02000041FFE349BB485456D39D020000415349BB588143D49D020000415349BB006043D49D02000041FFE349BBD05356D39D020000415349BB788143D49D020000415349BB006043D49D02000041FFE349BB585356D39D020000415349BB888143D49D020000415349BB006043D49D02000041FFE3 +[d4bd899e5b6] jit-backend-dump} +[d4bd899feba] {jit-backend-addr +Loop 1 ( #64 FOR_ITER) has address 0x29dd4438209 to 0x29dd443866b (bootstrap 0x29dd4438198) +[d4bd89a36c2] jit-backend-addr} +[d4bd89a4c38] {jit-backend-dump +BACKEND x86_64 +SYS_EXECUTABLE pypy +CODE_DUMP @29dd4438328 +0 3F030000 +[d4bd89a8146] jit-backend-dump} +[d4bd89c766a] {jit-backend-dump +BACKEND x86_64 +SYS_EXECUTABLE pypy +CODE_DUMP @29dd443833d +0 4F030000 +[d4bd89cb632] jit-backend-dump} +[d4bd89cc7b2] {jit-backend-dump +BACKEND x86_64 +SYS_EXECUTABLE pypy +CODE_DUMP @29dd443834b +0 66030000 +[d4bd89cf62e] jit-backend-dump} +[d4bd89d04ac] {jit-backend-dump +BACKEND x86_64 +SYS_EXECUTABLE pypy +CODE_DUMP @29dd4438361 +0 75030000 +[d4bd89d2d4c] jit-backend-dump} +[d4bd89d3bda] {jit-backend-dump +BACKEND x86_64 +SYS_EXECUTABLE pypy +CODE_DUMP @29dd4438372 +0 89030000 +[d4bd89d622c] jit-backend-dump} +[d4bd89d725c] {jit-backend-dump +BACKEND x86_64 +SYS_EXECUTABLE pypy +CODE_DUMP @29dd443838e +0 92030000 +[d4bd89d9b86] jit-backend-dump} +[d4bd89dadfa] {jit-backend-dump +BACKEND x86_64 +SYS_EXECUTABLE pypy +CODE_DUMP @29dd4438398 +0 AD030000 +[d4bd89dd794] jit-backend-dump} +[d4bd89de63e] {jit-backend-dump +BACKEND x86_64 +SYS_EXECUTABLE pypy +CODE_DUMP @29dd44383aa +0 C0030000 +[d4bd89e1648] jit-backend-dump} +[d4bd89e26b2] {jit-backend-dump +BACKEND x86_64 +SYS_EXECUTABLE pypy +CODE_DUMP @29dd4438432 +0 5D030000 +[d4bd89e4e34] jit-backend-dump} +[d4bd89e5ccc] {jit-backend-dump +BACKEND x86_64 +SYS_EXECUTABLE pypy +CODE_DUMP @29dd443844c +0 68030000 +[d4bd89e836c] jit-backend-dump} +[d4bd89e91b6] {jit-backend-dump +BACKEND x86_64 +SYS_EXECUTABLE pypy +CODE_DUMP @29dd443846a +0 6F030000 +[d4bd89eb7ba] jit-backend-dump} +[d4bd89ec5c8] {jit-backend-dump +BACKEND x86_64 +SYS_EXECUTABLE pypy +CODE_DUMP @29dd4438481 +0 7D030000 +[d4bd89eeb16] jit-backend-dump} +[d4bd89f0224] {jit-backend-dump +BACKEND x86_64 +SYS_EXECUTABLE pypy +CODE_DUMP @29dd44384ec +0 5C030000 +[d4bd89f27c0] jit-backend-dump} +[d4bd89f375c] {jit-backend-dump +BACKEND x86_64 +SYS_EXECUTABLE pypy +CODE_DUMP @29dd4438503 +0 6A030000 +[d4bd89f5e88] jit-backend-dump} +[d4bd89f6e3c] {jit-backend-dump +BACKEND x86_64 +SYS_EXECUTABLE pypy +CODE_DUMP @29dd4438540 +0 52030000 +[d4bd89f9804] jit-backend-dump} +[d4bd89fa622] {jit-backend-dump +BACKEND x86_64 +SYS_EXECUTABLE pypy +CODE_DUMP @29dd4438569 +0 4E030000 +[d4bd89fce48] jit-backend-dump} +[d4bd89fdc78] {jit-backend-dump +BACKEND x86_64 +SYS_EXECUTABLE pypy +CODE_DUMP @29dd44385d2 +0 0A030000 +[d4bd8a00248] jit-backend-dump} +[d4bd8a01288] {jit-backend-dump +BACKEND x86_64 +SYS_EXECUTABLE pypy +CODE_DUMP @29dd443863d +0 E9020000 +[d4bd8a03b30] jit-backend-dump} +[d4bd8a04982] {jit-backend-dump +BACKEND x86_64 +SYS_EXECUTABLE pypy +CODE_DUMP @29dd4438654 +0 F7020000 +[d4bd8a070a6] jit-backend-dump} +[d4bd8a0933e] jit-backend} +[d4bd8a0ddf6] {jit-log-opt-loop +# Loop 1 ( #64 FOR_ITER) : loop with 105 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: p16 = getfield_gc(p0, descr=) -+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] -debug_merge_point(0, 0, ' #12 LOAD_CONST') -+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] -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] -+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] -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] -+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] -debug_merge_point(1, 1, ' #0 LOAD_FAST') -debug_merge_point(1, 1, ' #3 LOAD_CONST') -debug_merge_point(1, 1, ' #6 BINARY_ADD') -+458: i36 = int_add(i21, 1) -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(51804288, descr=) -+471: i41 = int_lt(i39, 0) -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(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] -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] -debug_merge_point(0, 0, ' #24 LOAD_FAST') -debug_merge_point(0, 0, ' #27 CALL_FUNCTION') -+525: p44 = force_token() -debug_merge_point(1, 1, ' #0 LOAD_FAST') -debug_merge_point(1, 1, ' #3 LOAD_CONST') -debug_merge_point(1, 1, ' #6 BINARY_ADD') -+525: i45 = int_add(i36, 1) -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(51804288, descr=) -+537: i47 = int_lt(i46, 0) -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(140633495988848)) -+555: --end of the loop-- -[19c474bf9fca] jit-log-opt-loop} -[19c474c0e8bc] {jit-backend-dump -BACKEND x86_64 -SYS_EXECUTABLE python -CODE_DUMP @7fe7c97fb268 +0 E9C1010000 -[19c474c103d6] jit-backend-dump} -[19c474c10960] {jit-backend-dump -BACKEND x86_64 -SYS_EXECUTABLE python -CODE_DUMP @7fe7c97fb2cf +0 E9C9010000 -[19c474c1148a] jit-backend-dump} -[19c474c118f3] {jit-backend-dump -BACKEND x86_64 -SYS_EXECUTABLE python -CODE_DUMP @7fe7c97fb30d +0 E9FA010000 -[19c474c122f5] jit-backend-dump} -[19c47509a4c2] {jit-backend -[19c475193ba8] {jit-backend-dump -BACKEND x86_64 -SYS_EXECUTABLE python -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 @7fe7c97fb76d +0 27010000 -[19c4751aef16] jit-backend-dump} -[19c4751af4c9] {jit-backend-dump -BACKEND x86_64 -SYS_EXECUTABLE python -CODE_DUMP @7fe7c97fb779 +0 40010000 -[19c4751aff5c] jit-backend-dump} -[19c4751b03b0] {jit-backend-dump -BACKEND x86_64 -SYS_EXECUTABLE python -CODE_DUMP @7fe7c97fb786 +0 58010000 -[19c4751b0dcc] jit-backend-dump} -[19c4751b122c] {jit-backend-dump -BACKEND x86_64 -SYS_EXECUTABLE python -CODE_DUMP @7fe7c97fb79c +0 67010000 -[19c4751b1b28] jit-backend-dump} -[19c4751b2047] {jit-backend-dump -BACKEND x86_64 -SYS_EXECUTABLE python -CODE_DUMP @7fe7c97fb7b6 +0 72010000 -[19c4751b2928] jit-backend-dump} -[19c4751b2d6d] {jit-backend-dump -BACKEND x86_64 -SYS_EXECUTABLE python -CODE_DUMP @7fe7c97fb7bf +0 8E010000 -[19c4751b36fb] jit-backend-dump} -[19c4751b3b61] {jit-backend-dump -BACKEND x86_64 -SYS_EXECUTABLE python -CODE_DUMP @7fe7c97fb7de +0 94010000 -[19c4751b440d] jit-backend-dump} -[19c4751b4852] {jit-backend-dump -BACKEND x86_64 -SYS_EXECUTABLE python -CODE_DUMP @7fe7c97fb7f0 +0 A7010000 -[19c4751b5192] jit-backend-dump} -[19c4751b55cc] {jit-backend-dump -BACKEND x86_64 -SYS_EXECUTABLE python -CODE_DUMP @7fe7c97fb803 +0 B9010000 -[19c4751b5ead] jit-backend-dump} -[19c4751b6304] {jit-backend-dump -BACKEND x86_64 -SYS_EXECUTABLE python -CODE_DUMP @7fe7c97fb811 +0 D0010000 -[19c4751b6baa] jit-backend-dump} -[19c4751b71bc] {jit-backend-dump -BACKEND x86_64 -SYS_EXECUTABLE python -CODE_DUMP @7fe7c97fb823 +0 08020000 -[19c4751b7aa9] jit-backend-dump} -[19c4751b7ec5] {jit-backend-dump -BACKEND x86_64 -SYS_EXECUTABLE python -CODE_DUMP @7fe7c97fb851 +0 FF010000 -[19c4751b87ca] jit-backend-dump} -[19c4751b8c15] {jit-backend-dump -BACKEND x86_64 -SYS_EXECUTABLE python -CODE_DUMP @7fe7c97fb873 +0 02020000 -[19c4751b94d6] jit-backend-dump} -[19c4751b99a7] {jit-backend-dump -BACKEND x86_64 -SYS_EXECUTABLE python -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=) -+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: 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(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] -+277: p23 = getfield_gc(p15, descr=) -+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] -+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') -+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] -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] -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: 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') -+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] -+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') -+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') -+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') -+545: jump(p0, p1, p2, p3, p6, i52, i50, p15, i51, i30, i29, i28, descr=TargetToken(140633495989464)) -+560: --end of the loop-- -[19c475204f61] jit-log-opt-loop} -[19c47566fb6c] {jit-backend -[19c47596b738] {jit-backend-dump -BACKEND x86_64 -SYS_EXECUTABLE python -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 @7fe7c97fbd02 +0 71010000 -[19c475989294] jit-backend-dump} -[19c475989b43] {jit-backend-dump -BACKEND x86_64 -SYS_EXECUTABLE python -CODE_DUMP @7fe7c97fbd14 +0 84010000 -[19c47598a8c3] jit-backend-dump} -[19c47598ae17] {jit-backend-dump -BACKEND x86_64 -SYS_EXECUTABLE python -CODE_DUMP @7fe7c97fbd1e +0 9F010000 -[19c47598b818] jit-backend-dump} -[19c47598bc6c] {jit-backend-dump -BACKEND x86_64 -SYS_EXECUTABLE python -CODE_DUMP @7fe7c97fbd31 +0 B1010000 -[19c47598c665] jit-backend-dump} -[19c47598cacb] {jit-backend-dump -BACKEND x86_64 -SYS_EXECUTABLE python -CODE_DUMP @7fe7c97fbd42 +0 C5010000 -[19c47598d49a] jit-backend-dump} -[19c47598d8fa] {jit-backend-dump -BACKEND x86_64 -SYS_EXECUTABLE python -CODE_DUMP @7fe7c97fbd55 +0 D7010000 -[19c47598e2a2] jit-backend-dump} -[19c47598e6f7] {jit-backend-dump -BACKEND x86_64 -SYS_EXECUTABLE python -CODE_DUMP @7fe7c97fbd8d +0 C4010000 -[19c47598f0d7] jit-backend-dump} -[19c47598f58b] {jit-backend-dump -BACKEND x86_64 -SYS_EXECUTABLE python -CODE_DUMP @7fe7c97fbd9f +0 D7010000 -[19c47598ff0c] jit-backend-dump} -[19c475990358] {jit-backend-dump -BACKEND x86_64 -SYS_EXECUTABLE python -CODE_DUMP @7fe7c97fbdad +0 EE010000 -[19c475990cbc] jit-backend-dump} -[19c475991353] {jit-backend-dump -BACKEND x86_64 -SYS_EXECUTABLE python -CODE_DUMP @7fe7c97fbdca +0 1B020000 -[19c475991cea] jit-backend-dump} -[19c47599220b] {jit-backend-dump -BACKEND x86_64 -SYS_EXECUTABLE python -CODE_DUMP @7fe7c97fbdf6 +0 14020000 -[19c475992b2e] jit-backend-dump} -[19c47599305b] {jit-backend-dump -BACKEND x86_64 -SYS_EXECUTABLE python -CODE_DUMP @7fe7c97fbe09 +0 26020000 -[19c475993ac7] jit-backend-dump} -[19c475993f4b] {jit-backend-dump -BACKEND x86_64 -SYS_EXECUTABLE python -CODE_DUMP @7fe7c97fbe40 +0 14020000 -[19c47599496a] jit-backend-dump} -[19c475994dad] {jit-backend-dump -BACKEND x86_64 -SYS_EXECUTABLE python -CODE_DUMP @7fe7c97fbe51 +0 28020000 -[19c4759956f9] jit-backend-dump} -[19c475995c29] {jit-backend-dump -BACKEND x86_64 -SYS_EXECUTABLE python -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=) -+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(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] -debug_merge_point(0, 0, ' #18 LOAD_CONST') -+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] -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] -+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] -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] -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] -debug_merge_point(0, 0, ' #60 STORE_FAST') -debug_merge_point(0, 0, ' #63 LOAD_FAST') -debug_merge_point(0, 0, ' #66 LOAD_CONST') -debug_merge_point(0, 0, ' #69 INPLACE_ADD') -+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: i43 = getfield_raw(51804288, descr=) -+444: i45 = int_lt(i43, 0) -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(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] -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] -+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] -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] -debug_merge_point(0, 0, ' #60 STORE_FAST') -debug_merge_point(0, 0, ' #63 LOAD_FAST') -debug_merge_point(0, 0, ' #66 LOAD_CONST') -debug_merge_point(0, 0, ' #69 INPLACE_ADD') -+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: 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] -debug_merge_point(0, 0, ' #15 LOAD_FAST') -+618: jump(p0, p1, p2, p3, p6, i53, i54, descr=TargetToken(140633495990168)) -+623: --end of the loop-- -[19c4759ebff6] jit-log-opt-loop} -[19c475ad90fd] {jit-backend -[19c475b60e23] {jit-backend-dump -BACKEND x86_64 -SYS_EXECUTABLE python -CODE_DUMP @7fe7c97fc130 +0 48817D50FFFFFF007D2448C7442408FFFFFF0049BBF0C07FC9E77F00004C891C2449BB75A27FC9E77F000041FFD349BBF8E167CCE77F00004D8B0B498D510149BBF8E167CCE77F0000498913488B95580100004C8B4A10488B4A1848C74010000000004883F9020F85000000004D85C90F85000000004C8B8D38010000498B4968488B0425484CB601488D7820483B3C25684CB601761B49BB20C17FC9E77F00004C891C2449BBE3A97FC9E77F000041FFD348893C25484CB60148C700180C000041C6818D00000001488BBD5001000041F6410401740F415149BB2EA17FC9E77F000041FFD34989B980000000488BBD4801000041F6410401740F415149BB2EA17FC9E77F000041FFD34989795041F6410401740F415149BB2EA17FC9E77F000041FFD349BB38CF0CCAE77F00004D89597041C6818E0000000049C741600000000049C741780200000049C741582A000000F6410481741678105149BB91A17FC9E77F000041FFD379048049FF01488941104C8D481049C701180C0000488BBD6001000049897908F6410481741678105149BB91A17FC9E77F000041FFD379048049FF014C89491848C741200000000048C741280000000048C74130000000004C8960084889455848C745108042EA0149BB301068CCE77F00004C895D204889E84C8BBC24880000004C8BB424800000004C8B6C24784C8B642470488B5C2468488B6C24604881C498000000C349BB40FC96C9E77F0000415349BB00C17FC9E77F0000415349BB00A07FC9E77F000041FFE349BB986054CCE77F0000415349BB10C17FC9E77F0000415349BB00A07FC9E77F000041FFE3 -[19c475b67831] jit-backend-dump} -[19c475b68364] {jit-backend-dump -BACKEND x86_64 -SYS_EXECUTABLE python -CODE_DUMP @7fe7c97fc134 +0 22000000 -[19c475b68e8f] jit-backend-dump} -[19c475b693cb] {jit-backend-dump -BACKEND x86_64 -SYS_EXECUTABLE python -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 @7fe7c97fc199 +0 A0010000 -[19c475b6c292] jit-backend-dump} -[19c475b6c766] {jit-backend-dump -BACKEND x86_64 -SYS_EXECUTABLE python -CODE_DUMP @7fe7c97fc1a2 +0 BC010000 -[19c475b6d09d] jit-backend-dump} -[19c475b6d7ac] {jit-backend-dump -BACKEND x86_64 -SYS_EXECUTABLE python -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] -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] -+118: p15 = getfield_gc(p1, descr=) -+129: p16 = getfield_gc(p1, descr=) -p18 = new_with_vtable(ConstClass(W_IntObject)) -+193: setfield_gc(p1, 1, descr=) -setfield_gc(p1, p6, descr=) -setfield_gc(p1, p7, descr=) -setfield_gc(p1, ConstPtr(ptr20), descr=) -+306: setfield_gc(p1, 0, descr=) -+314: setfield_gc(p1, ConstPtr(ptr22), descr=) -+322: setfield_gc(p1, 2, descr=) -+330: setfield_gc(p1, 42, descr=) -setarrayitem_gc(p15, 0, p18, descr=) -p27 = new_with_vtable(ConstClass(W_IntObject)) -+381: setfield_gc(p27, i9, descr=) -setarrayitem_gc(p15, 1, p27, descr=) -+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-- -[19c475b92846] jit-log-opt-bridge} -[19c47608ae49] {jit-backend -[19c47620d562] {jit-backend-dump -BACKEND x86_64 -SYS_EXECUTABLE python -CODE_DUMP @7fe7c97fc568 +0 48817D50FFFFFF007D2448C7442408FFFFFF0049BB88C37FC9E77F00004C891C2449BB75A27FC9E77F000041FFD349BB10E267CCE77F0000498B034C8D780149BB10E267CCE77F00004D893B4C8BBD38010000498B470849BBB00007CAE77F00004C39D80F85000000004C8B701049BB900E0CCAE77F00004D39DE0F850000000049BBC8C37FC9E77F00004C895D2041BBA05B840041FFD3F6450401740D49BBFDA17FC9E77F000041FFD348C74520000000004C8B78504989EE4C8B68604D85ED0F85000000004C8B68404983FD000F85000000004C8B2C2500EFCE014981FDF0EED4010F85000000004C8B2C25807816034983FD000F8C000000004989ED48898570010000488B0425484CB601488DB840010000483B3C25684CB601761B49BB28C47FC9E77F00004C891C2449BBE3A97FC9E77F000041FFD348893C25484CB60148C700407E0100488DB89000000048C707C800000048C74708050000004C8D673849C70424180C00004D8D54241049C702180C00004D8D4A1049C701E82200004D8D411849C70070400000498D701848C706C800000048C7460800000000488D5E1048C703180600004C8973084C8BB57001000041F6460401740F415649BB2EA17FC9E77F000041FFD349895E50488B9538010000F6420401740E5249BB2EA17FC9E77F000041FFD34C896A1849C7442408010000004C8967104C89571849BB808554CCE77F00004D89580849C74010C01CF1014D89411049C74108010000004C894F204889786848C740780300000049BBA08554CCE77F00004C8958604C89783048C740581300000048897028C780880000001500000049BBB00007CAE77F00004C89580849BB38CF0CCAE77F00004C89587049BB60B57FC9E77F0000498B3348898578010000488B3C25484CB6014889F84801F7483B3C25684CB601761B49BB38C47FC9E77F00004C891C2449BBE3A97FC9E77F000041FFD348893C25484CB60148C7000800000049BB58B57FC9E77F0000498B334889705049BB58B57FC9E77F00004C895808488BB5780100004889B0380100004C89B04001000048899D8001000049BB204C56CCE77F00004C895D184889C749BB58C47FC9E77F00004C895D2049BB68B67FC9E77F000041FFD3F6450401740D49BBFDA17FC9E77F000041FFD348C7452000000000488178108042EA01743E4889C7488BB57801000049BB68C47FC9E77F00004C895D2041BB908D080141FFD3F6450401740D49BBFDA17FC9E77F000041FFD348C7452000000000EB13488B957801000048C7421800000000488B405848837D10000F850000000048833C2500E61503000F8500000000488B9570010000488B5A604885DB0F8500000000488B5A40488BB57801000048C74650000000004883FB000F8500000000488B5A504C8B7630480FB6BE8C000000F6420401740E5249BB2EA17FC9E77F000041FFD34C8972504885FF0F8500000000488BBD8001000048C74708000000008138180C00000F8500000000488B7808488B95600100004801FA0F8000000000488BBD680100004883C7010F8000000000488B0425807816034883F8000F8C0000000049BB28E267CCE77F0000498B03488D700149BB28E267CCE77F00004989334881FF102700000F8D0000000049BB00000000000000804C39DF0F84000000004889F8B9020000004889956001000048898568010000489948F7F94889D048C1FA3FBF020000004821D74801F84883F8000F8500000000488B85600100004883C0010F8000000000488BBD680100004883C701488B1425807816034883FA000F8C000000004889FB49BBCEBD7FC9E77F000041FFE349BB786254CCE77F0000415349BB98C37FC9E77F0000415349BB00A07FC9E77F000041FFE349BB587356CCE77F0000415349BBA8C37FC9E77F0000415349BB00A07FC9E77F000041FFE349BBE07256CCE77F0000415349BBB8C37FC9E77F0000415349BB00A07FC9E77F000041FFE349BB687256CCE77F0000415349BBD8C37FC9E77F0000415349BB00A07FC9E77F000041FFE349BBF07156CCE77F0000415349BBE8C37FC9E77F0000415349BB00A07FC9E77F000041FFE349BB787156CCE77F0000415349BBF8C37FC9E77F0000415349BB00A07FC9E77F000041FFE349BB007156CCE77F0000415349BB08C47FC9E77F0000415349BB00A07FC9E77F000041FFE349BB887056CCE77F0000415349BB18C47FC9E77F0000415349BB00A07FC9E77F000041FFE349BB204C56CCE77F0000415349BB48C47FC9E77F0000415349BB85A07FC9E77F000041FFE349BB107056CCE77F0000415349BB78C47FC9E77F0000415349BB85A07FC9E77F000041FFE349BB986F56CCE77F0000415349BB88C47FC9E77F0000415349BB00A07FC9E77F000041FFE349BB206F56CCE77F0000415349BB98C47FC9E77F0000415349BB00A07FC9E77F000041FFE349BBA86E56CCE77F0000415349BBA8C47FC9E77F0000415349BB00A07FC9E77F000041FFE349BB306E56CCE77F0000415349BBB8C47FC9E77F0000415349BB00A07FC9E77F000041FFE349BBB86D56CCE77F0000415349BBC8C47FC9E77F0000415349BB00A07FC9E77F000041FFE349BB406D56CCE77F0000415349BBD8C47FC9E77F0000415349BB00A07FC9E77F000041FFE349BBC86C56CCE77F0000415349BBE8C47FC9E77F0000415349BB00A07FC9E77F000041FFE349BB506C56CCE77F0000415349BBF8C47FC9E77F0000415349BB00A07FC9E77F000041FFE349BBD86B56CCE77F0000415349BB08C57FC9E77F0000415349BB00A07FC9E77F000041FFE349BB606B56CCE77F0000415349BB18C57FC9E77F0000415349BB00A07FC9E77F000041FFE349BBE86A56CCE77F0000415349BB28C57FC9E77F0000415349BB00A07FC9E77F000041FFE349BB706A56CCE77F0000415349BB38C57FC9E77F0000415349BB00A07FC9E77F000041FFE349BBF86956CCE77F0000415349BB48C57FC9E77F0000415349BB00A07FC9E77F000041FFE349BB806956CCE77F0000415349BB58C57FC9E77F0000415349BB00A07FC9E77F000041FFE3 -[19c4762283c4] jit-backend-dump} -[19c476229554] {jit-backend-dump -BACKEND x86_64 -SYS_EXECUTABLE python -CODE_DUMP @7fe7c97fc56c +0 26000000 -[19c47622a4ac] jit-backend-dump} -[19c47622a9be] {jit-backend-dump -BACKEND x86_64 -SYS_EXECUTABLE python -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 @7fe7c97fc5ce +0 C0040000 -[19c47622d7fc] jit-backend-dump} -[19c47622ddfa] {jit-backend-dump -BACKEND x86_64 -SYS_EXECUTABLE python -CODE_DUMP @7fe7c97fc5e5 +0 CE040000 -[19c47622e73d] jit-backend-dump} -[19c47622ed4f] {jit-backend-dump -BACKEND x86_64 -SYS_EXECUTABLE python -CODE_DUMP @7fe7c97fc62b +0 D2040000 -[19c47622f6b6] jit-backend-dump} -[19c47622faf5] {jit-backend-dump -BACKEND x86_64 -SYS_EXECUTABLE python -CODE_DUMP @7fe7c97fc639 +0 E9040000 -[19c4762303fd] jit-backend-dump} -[19c476230872] {jit-backend-dump -BACKEND x86_64 -SYS_EXECUTABLE python -CODE_DUMP @7fe7c97fc64e +0 1E050000 -[19c476231192] jit-backend-dump} -[19c4762315d1] {jit-backend-dump -BACKEND x86_64 -SYS_EXECUTABLE python -CODE_DUMP @7fe7c97fc660 +0 31050000 -[19c476231eb5] jit-backend-dump} -[19c4762322c8] {jit-backend-dump -BACKEND x86_64 -SYS_EXECUTABLE python -CODE_DUMP @7fe7c97fc918 +0 9E020000 -[19c476232b8c] jit-backend-dump} -[19c476232fec] {jit-backend-dump -BACKEND x86_64 -SYS_EXECUTABLE python -CODE_DUMP @7fe7c97fc927 +0 B4020000 -[19c476233926] jit-backend-dump} -[19c476233d6c] {jit-backend-dump -BACKEND x86_64 -SYS_EXECUTABLE python -CODE_DUMP @7fe7c97fc93b +0 C5020000 -[19c476236834] jit-backend-dump} -[19c476236d7c] {jit-backend-dump -BACKEND x86_64 -SYS_EXECUTABLE python -CODE_DUMP @7fe7c97fc958 +0 CD020000 -[19c47623773c] jit-backend-dump} -[19c476237b4c] {jit-backend-dump -BACKEND x86_64 -SYS_EXECUTABLE python -CODE_DUMP @7fe7c97fc989 +0 C1020000 -[19c476238442] jit-backend-dump} -[19c476238835] {jit-backend-dump -BACKEND x86_64 -SYS_EXECUTABLE python -CODE_DUMP @7fe7c97fc9a4 +0 CB020000 -[19c476239131] jit-backend-dump} -[19c476239535] {jit-backend-dump -BACKEND x86_64 -SYS_EXECUTABLE python -CODE_DUMP @7fe7c97fc9b8 +0 DC020000 -[19c476239e16] jit-backend-dump} -[19c47623a220] {jit-backend-dump -BACKEND x86_64 -SYS_EXECUTABLE python -CODE_DUMP @7fe7c97fc9c9 +0 F0020000 -[19c47623aae9] jit-backend-dump} -[19c47623b4a3] {jit-backend-dump -BACKEND x86_64 -SYS_EXECUTABLE python -CODE_DUMP @7fe7c97fc9db +0 28030000 -[19c47623bddb] jit-backend-dump} -[19c47623c1eb] {jit-backend-dump -BACKEND x86_64 -SYS_EXECUTABLE python -CODE_DUMP @7fe7c97fca06 +0 22030000 -[19c47623ca8a] jit-backend-dump} -[19c47623ce89] {jit-backend-dump -BACKEND x86_64 -SYS_EXECUTABLE python -CODE_DUMP @7fe7c97fca19 +0 34030000 -[19c47623d73a] jit-backend-dump} -[19c47623db4a] {jit-backend-dump -BACKEND x86_64 -SYS_EXECUTABLE python -CODE_DUMP @7fe7c97fca50 +0 22030000 -[19c47623e458] jit-backend-dump} -[19c47623e859] {jit-backend-dump -BACKEND x86_64 -SYS_EXECUTABLE python -CODE_DUMP @7fe7c97fca61 +0 36030000 -[19c47623f149] jit-backend-dump} -[19c47623f5ac] {jit-backend-dump -BACKEND x86_64 -SYS_EXECUTABLE python -CODE_DUMP @7fe7c97fca7e +0 63030000 -[19c47623fe90] jit-backend-dump} -[19c4762406c8] {jit-backend-dump -BACKEND x86_64 -SYS_EXECUTABLE python -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] -+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] -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] -+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] -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: p20 = getfield_gc(ConstPtr(ptr19), descr=) -+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') -debug_merge_point(1, 1, ' #19 FOR_ITER') -debug_merge_point(1, 1, ' #22 STORE_FAST') -debug_merge_point(1, 1, ' #25 LOAD_FAST') -debug_merge_point(1, 1, ' #28 LOAD_CONST') -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(51804288, descr=) -+242: i25 = int_lt(i23, 0) -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) -p30 = new_array(5, descr=) -p32 = new_with_vtable(ConstClass(W_IntObject)) -p34 = new_with_vtable(ConstClass(W_IntObject)) -p36 = new_with_vtable(26177128) -p38 = new_with_vtable(ConstClass(W_ListObject)) -p40 = new_array(0, descr=) -p42 = new_with_vtable(26169752) -+427: setfield_gc(p42, p15, descr=) -setfield_gc(p13, p42, descr=) -setfield_gc(p1, p26, 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, i6, i7] -+948: keepalive(p28) -+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] -+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] -+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] -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] -+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] -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] -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(51804288, descr=) -+1133: i73 = int_lt(i71, 0) -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(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] -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] -+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] -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] -debug_merge_point(0, 0, ' #60 STORE_FAST') -debug_merge_point(0, 0, ' #63 LOAD_FAST') -debug_merge_point(0, 0, ' #66 LOAD_CONST') -debug_merge_point(0, 0, ' #69 INPLACE_ADD') -+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(51804288, descr=) -+1296: i92 = int_lt(i90, 0) -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(140633495990168)) -+1322: --end of the loop-- -[19c4762c0a61] jit-log-opt-bridge} -[19c476497d1a] {jit-backend-dump -BACKEND x86_64 -SYS_EXECUTABLE python -CODE_DUMP @7fe7c97fbdbc +0 E903020000 -[19c47649be73] jit-backend-dump} -[19c47649c3b8] {jit-backend-dump -BACKEND x86_64 -SYS_EXECUTABLE python -CODE_DUMP @7fe7c97fbe60 +0 E93D020000 -[19c47649ce6f] jit-backend-dump} -[19c47649d42e] {jit-backend-dump -BACKEND x86_64 -SYS_EXECUTABLE python -CODE_DUMP @7fe7c97fc5e9 +0 E9EE040000 -[19c47649e0fb] jit-backend-dump} -[19c47649e5b2] {jit-backend-dump -BACKEND x86_64 -SYS_EXECUTABLE python -CODE_DUMP @7fe7c97fc63d +0 E909050000 -[19c47649efa7] jit-backend-dump} -[19c47649f437] {jit-backend-dump -BACKEND x86_64 -SYS_EXECUTABLE python -CODE_DUMP @7fe7c97fc9cd +0 E910030000 -[19c47649fddf] jit-backend-dump} -[19c4764a029c] {jit-backend-dump -BACKEND x86_64 -SYS_EXECUTABLE python -CODE_DUMP @7fe7c97fca70 +0 E94B030000 -[19c4764a0c44] jit-backend-dump} -[19c476926513] {jit-backend -[19c4769db8ef] {jit-backend-dump -BACKEND x86_64 -SYS_EXECUTABLE python -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 @7fe7c97fd0e4 +0 61030000 -[19c4769fb2d8] jit-backend-dump} -[19c4769fb916] {jit-backend-dump -BACKEND x86_64 -SYS_EXECUTABLE python -CODE_DUMP @7fe7c97fd0f8 +0 72030000 -[19c4769fc368] jit-backend-dump} -[19c4769fc7d1] {jit-backend-dump -BACKEND x86_64 -SYS_EXECUTABLE python -CODE_DUMP @7fe7c97fd105 +0 8A030000 -[19c4769fd141] jit-backend-dump} -[19c4769fd58f] {jit-backend-dump -BACKEND x86_64 -SYS_EXECUTABLE python -CODE_DUMP @7fe7c97fd119 +0 9B030000 -[19c4769fdf05] jit-backend-dump} -[19c4769fe36b] {jit-backend-dump -BACKEND x86_64 -SYS_EXECUTABLE python -CODE_DUMP @7fe7c97fd133 +0 A6030000 -[19c4769fec55] jit-backend-dump} -[19c4769ff071] {jit-backend-dump -BACKEND x86_64 -SYS_EXECUTABLE python -CODE_DUMP @7fe7c97fd13c +0 C2030000 -[19c4769ff94f] jit-backend-dump} -[19c4769ffd80] {jit-backend-dump -BACKEND x86_64 -SYS_EXECUTABLE python -CODE_DUMP @7fe7c97fd15b +0 C8030000 -[19c476a006ea] jit-backend-dump} -[19c476a00b26] {jit-backend-dump -BACKEND x86_64 -SYS_EXECUTABLE python -CODE_DUMP @7fe7c97fd16e +0 DA030000 -[19c476a01413] jit-backend-dump} -[19c476a0183b] {jit-backend-dump -BACKEND x86_64 -SYS_EXECUTABLE python -CODE_DUMP @7fe7c97fd185 +0 E8030000 -[19c476a0210a] jit-backend-dump} -[19c476a02535] {jit-backend-dump -BACKEND x86_64 -SYS_EXECUTABLE python -CODE_DUMP @7fe7c97fd19d +0 F5030000 -[19c476a02dba] jit-backend-dump} -[19c476a0345e] {jit-backend-dump -BACKEND x86_64 -SYS_EXECUTABLE python -CODE_DUMP @7fe7c97fd1b2 +0 2A040000 -[19c476a03d83] jit-backend-dump} -[19c476a041c6] {jit-backend-dump -BACKEND x86_64 -SYS_EXECUTABLE python -CODE_DUMP @7fe7c97fd212 +0 EF030000 -[19c476a04af7] jit-backend-dump} -[19c476a04fe6] {jit-backend-dump -BACKEND x86_64 -SYS_EXECUTABLE python -CODE_DUMP @7fe7c97fd22a +0 FC030000 -[19c476a058d0] jit-backend-dump} -[19c476a05cf8] {jit-backend-dump -BACKEND x86_64 -SYS_EXECUTABLE python -CODE_DUMP @7fe7c97fd292 +0 B9030000 -[19c476a06592] jit-backend-dump} -[19c476a069d4] {jit-backend-dump -BACKEND x86_64 -SYS_EXECUTABLE python -CODE_DUMP @7fe7c97fd2eb +0 85030000 -[19c476a096d4] jit-backend-dump} -[19c476a09f21] {jit-backend-dump -BACKEND x86_64 -SYS_EXECUTABLE python -CODE_DUMP @7fe7c97fd312 +0 83030000 -[19c476a0a999] jit-backend-dump} -[19c476a0aeb2] {jit-backend-dump -BACKEND x86_64 -SYS_EXECUTABLE python -CODE_DUMP @7fe7c97fd381 +0 5E030000 -[19c476a0b824] jit-backend-dump} -[19c476a0bc29] {jit-backend-dump -BACKEND x86_64 -SYS_EXECUTABLE python -CODE_DUMP @7fe7c97fd3e2 +0 22030000 -[19c476a0c4e6] jit-backend-dump} -[19c476a0c908] {jit-backend-dump -BACKEND x86_64 -SYS_EXECUTABLE python -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=) -+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: p19 = getarrayitem_gc(p9, 4, descr=) -+183: p21 = getarrayitem_gc(p9, 5, descr=) -+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(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] -+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] -+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] -+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') -+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') -+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') -+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') -+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') -+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') -+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') -+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') -+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') -+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') -+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') -+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 @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 @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] -+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-- -[19c476fd6fb4] jit-log-opt-loop} -[19c477229d40] {jit-backend -[19c47726a154] {jit-backend-dump -BACKEND x86_64 -SYS_EXECUTABLE python -CODE_DUMP @7fe7c97fd8c8 +0 48817D50FFFFFF007D2448C7442408FFFFFF0049BB88D87FC9E77F00004C891C2449BB75A27FC9E77F000041FFD349BBA0E267CCE77F00004D8B3B4D8D670149BBA0E267CCE77F00004D89234D8D65014D8B6E084D39EC0F8D000000004D8B7E404F0FB65427184983FA330F84000000004D8D5424014D39EA0F8C0000000048C745580000000048C7451000C6FA0148C74520000000004889E84C8BBC24880000004C8BB424800000004C8B6C24784C8B642470488B5C2468488B6C24604881C498000000C349BB800959CCE77F0000415349BB98D87FC9E77F0000415349BB00A07FC9E77F000041FFE349BBD80B59CCE77F0000415349BBA8D87FC9E77F0000415349BB00A07FC9E77F000041FFE349BB600B59CCE77F0000415349BBB8D87FC9E77F0000415349BB00A07FC9E77F000041FFE3 -[19c47727826a] jit-backend-dump} -[19c477278fc6] {jit-backend-dump -BACKEND x86_64 -SYS_EXECUTABLE python -CODE_DUMP @7fe7c97fd8cc +0 1C000000 -[19c477279d40] jit-backend-dump} -[19c47727a217] {jit-backend-dump -BACKEND x86_64 -SYS_EXECUTABLE python -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 @7fe7c97fd921 +0 69000000 -[19c47727ce56] jit-backend-dump} -[19c47727d5d9] {jit-backend-dump -BACKEND x86_64 -SYS_EXECUTABLE python -CODE_DUMP @7fe7c97fd935 +0 7A000000 -[19c47727deef] jit-backend-dump} -[19c47727e32c] {jit-backend-dump -BACKEND x86_64 -SYS_EXECUTABLE python -CODE_DUMP @7fe7c97fd943 +0 91000000 -[19c47727ec22] jit-backend-dump} -[19c47727f5b2] {jit-backend-dump -BACKEND x86_64 -SYS_EXECUTABLE python -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] -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] -+113: i11 = int_add(i3, 1) -+118: i12 = int_lt(i11, i4) -guard_false(i12, descr=) [i11, p1] -+127: finish(0, descr=) -+198: --end of the loop-- -[19c47728e83a] jit-log-opt-bridge} -[19c4775d7810] {jit-backend -[19c47760e455] {jit-backend-dump -BACKEND x86_64 -SYS_EXECUTABLE python -CODE_DUMP @7fe7c97fda30 +0 48817D50FFFFFF007D2448C7442408FFFFFF0049BB00DA7FC9E77F00004C891C2449BB75A27FC9E77F000041FFD349BBB8E267CCE77F00004D8B3B4D8D6F0149BBB8E267CCE77F00004D892B4D8B6E404F0FB67C15184983FF330F84000000004D8D7A014D8B56084D39D70F8C0000000048C745580000000048C7451000C6FA0148C74520000000004889E84C8BBC24880000004C8BB424800000004C8B6C24784C8B642470488B5C2468488B6C24604881C498000000C349BBC80C59CCE77F0000415349BB10DA7FC9E77F0000415349BB00A07FC9E77F000041FFE349BB300E59CCE77F0000415349BB20DA7FC9E77F0000415349BB00A07FC9E77F000041FFE3 -[19c4776123ca] jit-backend-dump} -[19c477612cb4] {jit-backend-dump -BACKEND x86_64 -SYS_EXECUTABLE python -CODE_DUMP @7fe7c97fda34 +0 1C000000 -[19c47761382f] jit-backend-dump} -[19c477613ce8] {jit-backend-dump -BACKEND x86_64 -SYS_EXECUTABLE python -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} From noreply at buildbot.pypy.org Thu Sep 5 17:09:47 2013 From: noreply at buildbot.pypy.org (vext01) Date: Thu, 5 Sep 2013 17:09:47 +0200 (CEST) Subject: [pypy-commit] jitviewer argparse-collect: Add argparse support. Message-ID: <20130905150947.4D8191C0710@cobra.cs.uni-duesseldorf.de> Author: Edd Barrett Branch: argparse-collect Changeset: r232:b85bf2cf7df0 Date: 2013-08-30 17:55 +0100 http://bitbucket.org/pypy/jitviewer/changeset/b85bf2cf7df0/ Log: Add argparse support. diff --git a/_jitviewer/app.py b/_jitviewer/app.py --- a/_jitviewer/app.py +++ b/_jitviewer/app.py @@ -19,6 +19,7 @@ import sys import os.path +import argparse try: import pypy @@ -194,16 +195,15 @@ orig___init__(self2, *args, **kwds) BaseServer.__init__ = __init__ -def collect_log(interp, args, logpath="log.pypylog"): +def collect_log(args, logpath="log.pypylog"): """ Collect a log file using pypy """ # XXX Randomise log file name # XXX Search path import subprocess - print("prog: %s args: %s" % (interp, args)) - p = subprocess.Popen([interp] + args, + p = subprocess.Popen(args, env={"PYPYLOG" : "jit-log-opt,jit-backend:%s" % (logpath, )} ) p.communicate() @@ -215,39 +215,28 @@ if not '__pypy__' in sys.builtin_module_names: print "Please run it using pypy-c" sys.exit(1) - # - # XXX use argparse - server_mode = True - collect_mode = False - if '--qt' in argv: - server_mode = False - argv.remove('--qt') - if '--collect' in argv: - prog_args = argv[argv.index('--collect')+1:] - prog = prog_args[0] - args = prog_args[1:] - collect_mode = True - argv.remove('--collect') - # - if not collect_mode and len(argv) != 2 and len(argv) != 3: - print __doc__ - sys.exit(1) - if collect_mode: - print("YO COLLECT MODE") - print(72 * ":") - filename = collect_log(prog, args) - port = 5000 # XXX ugh + parser = argparse.ArgumentParser() + + parser.add_argument("-l", "--log", help="Specify logfile") + parser.add_argument("-c", "--collect", nargs="*", help="Collect logfile now") + parser.add_argument("-p", "--port", help="Select HTTP port") + parser.add_argument("-q", "--qt", action="store_true", help="Use QT") + + args = parser.parse_args() + + if args.port is not None: + port = int(args.port) else: - print("FUDGE") - print(72 * ":") - # XXX we really need argparse, as we cant specify port if collecting now - filename = argv[1] + port = 5000 - if len(argv) != 3: - port = 5000 - else: - port = int(argv[2]) + if args.collect is not None: + if len(args.collect) == 0: + print("*Error: Please specify invokation to collect log") + sys.exit(1) + filename = collect_log(args.collect) + else: + filename = args.log extra_path = os.path.dirname(filename) storage = LoopStorage(extra_path) @@ -266,7 +255,7 @@ def run(): app.run(use_reloader=bool(os.environ.get('JITVIEWER_USE_RELOADER', False)), host='0.0.0.0', port=port) - if server_mode: + if not args.qt: run() else: url = "http://localhost:%d/" % port From noreply at buildbot.pypy.org Thu Sep 5 17:09:48 2013 From: noreply at buildbot.pypy.org (vext01) Date: Thu, 5 Sep 2013 17:09:48 +0200 (CEST) Subject: [pypy-commit] jitviewer argparse-collect: Improve argparser. Message-ID: <20130905150948.555531C0710@cobra.cs.uni-duesseldorf.de> Author: Edd Barrett Branch: argparse-collect Changeset: r233:3c3cc5ada9e6 Date: 2013-08-30 22:58 +0100 http://bitbucket.org/pypy/jitviewer/changeset/3c3cc5ada9e6/ Log: Improve argparser. diff --git a/_jitviewer/app.py b/_jitviewer/app.py --- a/_jitviewer/app.py +++ b/_jitviewer/app.py @@ -1,20 +1,18 @@ #!/usr/bin/env pypy -""" A web-based browser of your log files. Run by - jitviewer.py [port] [--qt] +DESCR = """Jit Viewer: A web-based browser for PyPy log files""" + +EPILOG = """ +Typical usage with existing log file: + + jitviewer.py --log + +Typical usage with no existing log file: + + jitviewer.py --collect pypy ... By default the script will run a web server, point your browser to http://localhost:5000 - -If you pass --qt, this script will also start a lightweight PyQT/QWebKit based -browser pointing at the jitviewer. This assumes that CPython is installed in -/usr/bin/python, and that PyQT with WebKit support is installed. - -Demo logfile available in this directory as 'log'. - -To produce the logfile for your program, run: - - PYPYLOG=jit-log-opt,jit-backend:mylogfile.pypylog pypy myapp.py """ import sys @@ -216,27 +214,32 @@ print "Please run it using pypy-c" sys.exit(1) - parser = argparse.ArgumentParser() + parser = argparse.ArgumentParser( + description = DESCR, + epilog = EPILOG, + formatter_class=argparse.RawDescriptionHelpFormatter + ) - parser.add_argument("-l", "--log", help="Specify logfile") - parser.add_argument("-c", "--collect", nargs="*", help="Collect logfile now") - parser.add_argument("-p", "--port", help="Select HTTP port") - parser.add_argument("-q", "--qt", action="store_true", help="Use QT") + parser.add_argument("-l", "--log", help="specify existing logfile") + parser.add_argument("-c", "--collect", nargs="*", help="collect logfile now", metavar="ARG") + parser.add_argument("-p", "--port", help="select HTTP port", type=int) + parser.add_argument("-q", "--qt", action="store_true", help="use embedded QT browser") args = parser.parse_args() - if args.port is not None: - port = int(args.port) - else: - port = 5000 + if args.port is None: + args.port = 5000 if args.collect is not None: if len(args.collect) == 0: print("*Error: Please specify invokation to collect log") sys.exit(1) filename = collect_log(args.collect) + elif args.log is not None: + filename = args.log else: - filename = args.log + print("*Error: Please specify either --log or --collect") + sys.exit(1) extra_path = os.path.dirname(filename) storage = LoopStorage(extra_path) @@ -253,12 +256,12 @@ app.route('/loop')(server.loop) if run_app: def run(): - app.run(use_reloader=bool(os.environ.get('JITVIEWER_USE_RELOADER', False)), host='0.0.0.0', port=port) + app.run(use_reloader=bool(os.environ.get('JITVIEWER_USE_RELOADER', False)), host='0.0.0.0', port=args.port) if not args.qt: run() else: - url = "http://localhost:%d/" % port + url = "http://localhost:%d/" % args.port run_server_and_browser(app, run, url, filename) else: return app From noreply at buildbot.pypy.org Thu Sep 5 17:09:49 2013 From: noreply at buildbot.pypy.org (vext01) Date: Thu, 5 Sep 2013 17:09:49 +0200 (CEST) Subject: [pypy-commit] jitviewer argparse-collect: Make the page title render, improve styling on page. Message-ID: <20130905150949.6263A1C0710@cobra.cs.uni-duesseldorf.de> Author: Edd Barrett Branch: argparse-collect Changeset: r234:d7e9839552ac Date: 2013-08-30 23:16 +0100 http://bitbucket.org/pypy/jitviewer/changeset/d7e9839552ac/ Log: Make the page title render, improve styling on page. diff --git a/_jitviewer/static/style.css b/_jitviewer/static/style.css --- a/_jitviewer/static/style.css +++ b/_jitviewer/static/style.css @@ -1,5 +1,5 @@ /*HTML5 Reset*/ -a,abbr,address,article,aside,audio,b,blockquote,body,canvas,caption,cite,code,dd,del,details,dfn,div,dl,dt,em,embed,fieldset,figcaption,figure,footer,form,h1,h2,h3,h4,h5,h6,header,hgroup,html,i,iframe,img,ins,kbd,label,legend,li,mark,menu,nav,object,ol,p,pre,q,samp,section,small,span,strong,sub,summary,sup,table,tbody,td,tfoot,th,thead,time,tr,ul,var,video{ margin:0; padding:0; border:0; font-size:100%; font-weight:inherit; font-style:inherit; vertical-align:baseline}article,aside,canvas,details,figcaption,figure,footer,header,hgroup,menu,nav,section,summary{ display:block}a,ins,del{ text-decoration:none}ul,ol{ list-style:none}table{ border-spacing:0; border-collapse:collapse}caption,th{ text-align:left}q:after,q:before{ content:��} +a,abbr,address,article,aside,audio,b,blockquote,body,canvas,caption,cite,code,dd,del,details,dfn,div,dl,dt,em,embed,fieldset,figcaption,figure,footer,form,h2,h3,h4,h5,h6,header,hgroup,html,i,iframe,img,ins,kbd,label,legend,li,mark,menu,nav,object,ol,p,pre,q,samp,section,small,span,strong,sub,summary,sup,table,tbody,td,tfoot,th,thead,time,tr,ul,var,video{ margin:0; padding:0; border:0; font-size:100%; font-weight:inherit; font-style:inherit; vertical-align:baseline}article,aside,canvas,details,figcaption,figure,footer,header,hgroup,menu,nav,section,summary{ display:block}a,ins,del{ text-decoration:none}ul,ol{ list-style:none}table{ border-spacing:0; border-collapse:collapse}caption,th{ text-align:left}q:after,q:before{ content:��} /*End of HTML5 Reset*/ /* General Layout & Typography @@ -232,6 +232,16 @@ font-weight: bold; } +.menu { + background: #cccccc; + text-color: red; +} + +h1 { + padding: 10px 10px 10px 10px; + background: #ffcc66; +} + /* End of Formatting -----------------------------------------*/ diff --git a/_jitviewer/templates/index.html b/_jitviewer/templates/index.html --- a/_jitviewer/templates/index.html +++ b/_jitviewer/templates/index.html @@ -19,15 +19,18 @@
    - Menu
    + Show assembler [a]
    Show bytecode position [b]
    +

    JIT Viewer

    +
    Filter [/]:
    From noreply at buildbot.pypy.org Thu Sep 5 17:09:50 2013 From: noreply at buildbot.pypy.org (vext01) Date: Thu, 5 Sep 2013 17:09:50 +0200 (CEST) Subject: [pypy-commit] jitviewer argparse-collect: Remove spurious whitespace in css. Message-ID: <20130905150950.673421C0710@cobra.cs.uni-duesseldorf.de> Author: Edd Barrett Branch: argparse-collect Changeset: r235:a817db23e180 Date: 2013-08-30 23:17 +0100 http://bitbucket.org/pypy/jitviewer/changeset/a817db23e180/ Log: Remove spurious whitespace in css. diff --git a/_jitviewer/static/style.css b/_jitviewer/static/style.css --- a/_jitviewer/static/style.css +++ b/_jitviewer/static/style.css @@ -244,15 +244,3 @@ /* End of Formatting -----------------------------------------*/ - - - - - - - - - - - - From noreply at buildbot.pypy.org Thu Sep 5 17:09:51 2013 From: noreply at buildbot.pypy.org (vext01) Date: Thu, 5 Sep 2013 17:09:51 +0200 (CEST) Subject: [pypy-commit] jitviewer argparse-collect: Search the PATH when invoking pypy interpreter for log collection. Message-ID: <20130905150951.5B2BF1C0710@cobra.cs.uni-duesseldorf.de> Author: Edd Barrett Branch: argparse-collect Changeset: r236:a4f3ed9615b6 Date: 2013-08-30 23:35 +0100 http://bitbucket.org/pypy/jitviewer/changeset/a4f3ed9615b6/ Log: Search the PATH when invoking pypy interpreter for log collection. diff --git a/_jitviewer/app.py b/_jitviewer/app.py --- a/_jitviewer/app.py +++ b/_jitviewer/app.py @@ -197,14 +197,14 @@ """ Collect a log file using pypy """ # XXX Randomise log file name - # XXX Search path import subprocess - p = subprocess.Popen(args, - env={"PYPYLOG" : "jit-log-opt,jit-backend:%s" % (logpath, )} - ) - p.communicate() + # possibly make this configurable if someone asks... + os.environ["PYPYLOG"] = "jit-log-opt,jit-backend:%s" % (logpath, ) + print("Collecting log...") + p = subprocess.Popen(args, env=os.environ).communicate() + # We don't check the return status. The user may want to see traces # for a failing program! return os.path.abspath(logpath) From noreply at buildbot.pypy.org Thu Sep 5 17:09:52 2013 From: noreply at buildbot.pypy.org (vext01) Date: Thu, 5 Sep 2013 17:09:52 +0200 (CEST) Subject: [pypy-commit] jitviewer argparse-collect: On second thoughts, dont erase h1 from html5 reset code. Message-ID: <20130905150952.533151C0710@cobra.cs.uni-duesseldorf.de> Author: Edd Barrett Branch: argparse-collect Changeset: r237:e9ca5ad876b4 Date: 2013-08-30 23:42 +0100 http://bitbucket.org/pypy/jitviewer/changeset/e9ca5ad876b4/ Log: On second thoughts, dont erase h1 from html5 reset code. diff --git a/_jitviewer/static/style.css b/_jitviewer/static/style.css --- a/_jitviewer/static/style.css +++ b/_jitviewer/static/style.css @@ -1,5 +1,5 @@ /*HTML5 Reset*/ -a,abbr,address,article,aside,audio,b,blockquote,body,canvas,caption,cite,code,dd,del,details,dfn,div,dl,dt,em,embed,fieldset,figcaption,figure,footer,form,h2,h3,h4,h5,h6,header,hgroup,html,i,iframe,img,ins,kbd,label,legend,li,mark,menu,nav,object,ol,p,pre,q,samp,section,small,span,strong,sub,summary,sup,table,tbody,td,tfoot,th,thead,time,tr,ul,var,video{ margin:0; padding:0; border:0; font-size:100%; font-weight:inherit; font-style:inherit; vertical-align:baseline}article,aside,canvas,details,figcaption,figure,footer,header,hgroup,menu,nav,section,summary{ display:block}a,ins,del{ text-decoration:none}ul,ol{ list-style:none}table{ border-spacing:0; border-collapse:collapse}caption,th{ text-align:left}q:after,q:before{ content:��} +a,abbr,address,article,aside,audio,b,blockquote,body,canvas,caption,cite,code,dd,del,details,dfn,div,dl,dt,em,embed,fieldset,figcaption,figure,footer,form,h1,h2,h3,h4,h5,h6,header,hgroup,html,i,iframe,img,ins,kbd,label,legend,li,mark,menu,nav,object,ol,p,pre,q,samp,section,small,span,strong,sub,summary,sup,table,tbody,td,tfoot,th,thead,time,tr,ul,var,video{ margin:0; padding:0; border:0; font-size:100%; font-weight:inherit; font-style:inherit; vertical-align:baseline}article,aside,canvas,details,figcaption,figure,footer,header,hgroup,menu,nav,section,summary{ display:block}a,ins,del{ text-decoration:none}ul,ol{ list-style:none}table{ border-spacing:0; border-collapse:collapse}caption,th{ text-align:left}q:after,q:before{ content:��} /*End of HTML5 Reset*/ /* General Layout & Typography @@ -240,6 +240,7 @@ h1 { padding: 10px 10px 10px 10px; background: #ffcc66; + font-size: 25px; } /* End of Formatting From noreply at buildbot.pypy.org Thu Sep 5 17:09:53 2013 From: noreply at buildbot.pypy.org (vext01) Date: Thu, 5 Sep 2013 17:09:53 +0200 (CEST) Subject: [pypy-commit] jitviewer argparse-collect: Randomize log file path using mkstemp() Message-ID: <20130905150953.4BDE01C0710@cobra.cs.uni-duesseldorf.de> Author: Edd Barrett Branch: argparse-collect Changeset: r238:c980aabe1684 Date: 2013-08-30 23:57 +0100 http://bitbucket.org/pypy/jitviewer/changeset/c980aabe1684/ Log: Randomize log file path using mkstemp() diff --git a/_jitviewer/app.py b/_jitviewer/app.py --- a/_jitviewer/app.py +++ b/_jitviewer/app.py @@ -193,21 +193,22 @@ orig___init__(self2, *args, **kwds) BaseServer.__init__ = __init__ -def collect_log(args, logpath="log.pypylog"): +def collect_log(args): """ Collect a log file using pypy """ + import tempfile, subprocess - # XXX Randomise log file name - - import subprocess + # create a temp file, possibly racey, but very unlikey + (fd, path) = tempfile.mkstemp(prefix="jitviewer-") + os.close(fd) # just the filename we want # possibly make this configurable if someone asks... - os.environ["PYPYLOG"] = "jit-log-opt,jit-backend:%s" % (logpath, ) - print("Collecting log...") + os.environ["PYPYLOG"] = "jit-log-opt,jit-backend:%s" % (path, ) + print("Collecting log in '%s'..." % path) p = subprocess.Popen(args, env=os.environ).communicate() # We don't check the return status. The user may want to see traces # for a failing program! - return os.path.abspath(logpath) + return os.path.abspath(path) def main(argv, run_app=True): if not '__pypy__' in sys.builtin_module_names: From noreply at buildbot.pypy.org Thu Sep 5 17:09:54 2013 From: noreply at buildbot.pypy.org (vext01) Date: Thu, 5 Sep 2013 17:09:54 +0200 (CEST) Subject: [pypy-commit] jitviewer argparse-collect: Put back original example log file. Message-ID: <20130905150954.578141C0710@cobra.cs.uni-duesseldorf.de> Author: Edd Barrett Branch: argparse-collect Changeset: r239:94a4fbc83bb1 Date: 2013-08-31 00:00 +0100 http://bitbucket.org/pypy/jitviewer/changeset/94a4fbc83bb1/ Log: Put back original example log file. diff too long, truncating to 2000 out of 3744 lines diff --git a/log.pypylog b/log.pypylog --- a/log.pypylog +++ b/log.pypylog @@ -1,699 +1,3117 @@ -[d4bd435c340] {jit-backend-dump +[19c473e15553] {jit-backend-dump BACKEND x86_64 -SYS_EXECUTABLE pypy -CODE_DUMP @29dd4436000 +0 48894D58488945604889556848895D70488975784889BD800000004C8985880000004C898D900000004C8995980000004C89A5A00000004C89ADA80000004C89B5B00000004C89BDB8000000584889452058488945104889E848BB30CF61CD9902000048832B084C8BBC24880000004C8BB424800000004C8B6C24784C8B642470488B5C2468488B6C24604881C498000000C3 -[d4bd43dff40] jit-backend-dump} -[d4bd43e968a] {jit-backend-dump +SYS_EXECUTABLE python +CODE_DUMP @7fe7c97fa000 +0 48894D58488945604889556848895D70488975784889BD800000004C8985880000004C898D900000004C8995980000004C89A5A00000004C89ADA80000004C89B5B00000004C89BDB8000000584889452058488945104889E84C8BBC24880000004C8BB424800000004C8B6C24784C8B642470488B5C2468488B6C24604881C498000000C3 +[19c473e25f71] jit-backend-dump} +[19c473e2c5ce] {jit-backend-dump BACKEND x86_64 -SYS_EXECUTABLE pypy -CODE_DUMP @29dd4436093 +0 48894D58488945604889556848895D70488975784889BD800000004C8985880000004C898D900000004C8995980000004C89A5A00000004C89ADA80000004C89B5B00000004C89BDB800000049BB48D3E5CE99020000498B1B49BB40D3E5CE9902000049C7030000000049BB48D3E5CE9902000049C7030000000048895D38584889452058488945104889E848BB30CF61CD9902000048832B084C8BBC24880000004C8BB424800000004C8B6C24784C8B642470488B5C2468488B6C24604881C498000000C3 -[d4bd43f3eaa] jit-backend-dump} -[d4bd43f8304] {jit-backend-dump +SYS_EXECUTABLE python +CODE_DUMP @7fe7c97fa085 +0 48894D58488945604889556848895D70488975784889BD800000004C8985880000004C898D900000004C8995980000004C89A5A00000004C89ADA80000004C89B5B00000004C89BDB8000000488B1C2508E6150348C7042500E615030000000048C7042508E615030000000048895D38584889452058488945104889E84C8BBC24880000004C8BB424800000004C8B6C24784C8B642470488B5C2468488B6C24604881C498000000C3 +[19c473e2ecc8] jit-backend-dump} +[19c473e31f04] {jit-backend-dump BACKEND x86_64 -SYS_EXECUTABLE pypy -CODE_DUMP @29dd4436159 +0 4889455848894D60488955684889757048897D784C8985800000004C898D880000004C899590000000488B7C240849BBD01AD1CC9902000041FFD3488B4558488B4D60488B5568488B7570488B7D784C8B85800000004C8B8D880000004C8B9590000000C20800 -[d4bd440fc6c] jit-backend-dump} -[d4bd441924a] {jit-backend-dump +SYS_EXECUTABLE python +CODE_DUMP @7fe7c97fa12e +0 4889455848894D60488955684889757048897D784C8985800000004C898D880000004C899590000000488B7C240841BBB064120141FFD3488B4558488B4D60488B5568488B7570488B7D784C8B85800000004C8B8D880000004C8B9590000000C20800 +[19c473e338a2] jit-backend-dump} +[19c473e366e6] {jit-backend-dump BACKEND x86_64 -SYS_EXECUTABLE pypy -CODE_DUMP @29dd44361c0 +0 4889455848894D60488955684889757048897D784C8985800000004C898D880000004C899590000000488B7C240849BB101CD1CC9902000041FFD3488B442408F6400480488B4558488B4D60488B5568488B7570488B7D784C8B85800000004C8B8D880000004C8B9590000000C20800 -[d4bd441fdd0] jit-backend-dump} -[d4bd457435c] {jit-backend-dump +SYS_EXECUTABLE python +CODE_DUMP @7fe7c97fa191 +0 4889455848894D60488955684889757048897D784C8985800000004C898D880000004C899590000000488B7C240841BBF065120141FFD3488B442408F6400480488B4558488B4D60488B5568488B7570488B7D784C8B85800000004C8B8D880000004C8B9590000000C20800 +[19c473e38072] jit-backend-dump} +[19c473e3b5e9] {jit-backend-dump BACKEND x86_64 -SYS_EXECUTABLE pypy -CODE_DUMP @29dd4436230 +0 4883EC384889442408F20F114424184889EF48895C24284C8964243049BB48D3E5CE99020000498B1B49BB40D3E5CE990200004D8B2349BB40D3E5CE9902000049C7030000000049BB48D3E5CE9902000049C7030000000049BBD01AD1CC9902000041FFD3F20F10442418488B44240849BB48D3E5CE9902000049891B49BB40D3E5CE990200004D8923488B5C24284C8B642430488D642438C3 -[d4bd457e70a] jit-backend-dump} -[d4bd4586ce6] {jit-backend-dump +SYS_EXECUTABLE python +CODE_DUMP @7fe7c97fa1fd +0 4883EC384889442408F20F114424184889EF48895C24284C89642430488B1C2508E615034C8B242500E6150348C7042500E615030000000048C7042508E615030000000041BBB064120141FFD3F20F10442418488B44240848891C2508E615034C89242500E61503488B5C24284C8B642430488D642438C3 +[19c473e3d069] jit-backend-dump} +[19c473e40c38] {jit-backend-dump BACKEND x86_64 -SYS_EXECUTABLE pypy -CODE_DUMP @29dd44362ca +0 48894D58488945604889556848895D70488975784889BD800000004C8985880000004C898D900000004C8995980000004C89A5A00000004C89ADA80000004C89B5B00000004C89BDB8000000F20F1185C0000000F20F118DC8000000F20F1195D0000000F20F119DD8000000F20F11A5E0000000F20F11ADE8000000F20F11B5F0000000F20F11BDF8000000F2440F118500010000F2440F118D08010000F2440F119510010000F2440F119D18010000F2440F11A520010000F2440F11AD28010000F2440F11B530010000488B4C240848894D20488B7424104889EF4883EC0849BB48D3E5CE99020000498B0B48894D3849BB40D3E5CE99020000498B1B49BB40D3E5CE9902000049C7030000000049BB48D3E5CE9902000049C7030000000049BB90D89FCC9902000041FFD34889C5488B4D3848C745380000000049BB48D3E5CE9902000049890B49BB40D3E5CE9902000049891B4883C40849BB30CF61CD99020000498B1B488943F848C7452000000000488B4D58488B4560488B5568488B5D70488B7578488BBD800000004C8B85880000004C8B8D900000004C8B95980000004C8BA5A00000004C8BADA80000004C8BB5B00000004C8BBDB8000000F20F1085C0000000F20F108DC8000000F20F1095D0000000F20F109DD8000000F20F10A5E0000000F20F10ADE8000000F20F10B5F0000000F20F10BDF8000000F2440F108500010000F2440F108D08010000F2440F109510010000F2440F109D18010000F2440F10A520010000F2440F10AD28010000F2440F10B530010000C3 -[d4bd459ae14] jit-backend-dump} -[d4bd459f028] {jit-backend-dump +SYS_EXECUTABLE python +CODE_DUMP @7fe7c97fa275 +0 48894D58488945604889556848895D70488975784889BD800000004C8985880000004C898D900000004C8995980000004C89A5A00000004C89ADA80000004C89B5B00000004C89BDB8000000F20F1185C0000000F20F118DC8000000F20F1195D0000000F20F119DD8000000F20F11A5E0000000F20F11ADE8000000F20F11B5F0000000F20F11BDF8000000F2440F118500010000F2440F118D08010000F2440F119510010000F2440F119D18010000F2440F11A520010000F2440F11AD28010000F2440F11B530010000488B4C240848894D20488B7424104889EF4883EC0848C7452810000000488B0C2508E6150348894D38488B1C2500E6150348C7042500E615030000000048C7042508E615030000000041BB60DBE80041FFD34889C5488B4D3848C745380000000048890C2508E6150348891C2500E615034883C40848C745280000000048C7452000000000488B4D58488B4560488B5568488B5D70488B7578488BBD800000004C8B85880000004C8B8D900000004C8B95980000004C8BA5A00000004C8BADA80000004C8BB5B00000004C8BBDB8000000F20F1085C0000000F20F108DC8000000F20F1095D0000000F20F109DD8000000F20F10A5E0000000F20F10ADE8000000F20F10B5F0000000F20F10BDF8000000F2440F108500010000F2440F108D08010000F2440F109510010000F2440F109D18010000F2440F10A520010000F2440F10AD28010000F2440F10B530010000C3 +[19c473e45561] jit-backend-dump} +[19c473e467bb] {jit-backend-dump BACKEND x86_64 -SYS_EXECUTABLE pypy -CODE_DUMP @29dd4436509 +0 48894D58488945604889556848895D70488975784889BD800000004C8985880000004C898D900000004C8995980000004C89A5A00000004C89ADA80000004C89B5B00000004C89BDB8000000F20F1185C0000000F20F118DC8000000F20F1195D0000000F20F119DD8000000F20F11A5E0000000F20F11ADE8000000F20F11B5F0000000F20F11BDF8000000F2440F118500010000F2440F118D08010000F2440F119510010000F2440F119D18010000F2440F11A520010000F2440F11AD28010000F2440F11B530010000584889452058488945104889E848BB30CF61CD9902000048832B084C8BBC24880000004C8BB424800000004C8B6C24784C8B642470488B5C2468488B6C24604881C498000000C3 -[d4bd45aa7fc] jit-backend-dump} -[d4bd45ae4f6] {jit-backend-dump +SYS_EXECUTABLE python +CODE_DUMP @7fe7c97fa491 +0 48894D58488945604889556848895D70488975784889BD800000004C8985880000004C898D900000004C8995980000004C89A5A00000004C89ADA80000004C89B5B00000004C89BDB8000000F20F1185C0000000F20F118DC8000000F20F1195D0000000F20F119DD8000000F20F11A5E0000000F20F11ADE8000000F20F11B5F0000000F20F11BDF8000000F2440F118500010000F2440F118D08010000F2440F119510010000F2440F119D18010000F2440F11A520010000F2440F11AD28010000F2440F11B530010000584889452058488945104889E84C8BBC24880000004C8BB424800000004C8B6C24784C8B642470488B5C2468488B6C24604881C498000000C3 +[19c473e48f8b] jit-backend-dump} +[19c473e4a206] {jit-backend-dump BACKEND x86_64 -SYS_EXECUTABLE pypy -CODE_DUMP @29dd443661b +0 48894D58488945604889556848895D70488975784889BD800000004C8985880000004C898D900000004C8995980000004C89A5A00000004C89ADA80000004C89B5B00000004C89BDB8000000F20F1185C0000000F20F118DC8000000F20F1195D0000000F20F119DD8000000F20F11A5E0000000F20F11ADE8000000F20F11B5F0000000F20F11BDF8000000F2440F118500010000F2440F118D08010000F2440F119510010000F2440F119D18010000F2440F11A520010000F2440F11AD28010000F2440F11B53001000049BB48D3E5CE99020000498B1B49BB40D3E5CE9902000049C7030000000049BB48D3E5CE9902000049C7030000000048895D38584889452058488945104889E848BB30CF61CD9902000048832B084C8BBC24880000004C8BB424800000004C8B6C24784C8B642470488B5C2468488B6C24604881C498000000C3 -[d4bd45cae42] jit-backend-dump} -[d4bd45cf30e] {jit-backend-dump +SYS_EXECUTABLE python +CODE_DUMP @7fe7c97fa595 +0 48894D58488945604889556848895D70488975784889BD800000004C8985880000004C898D900000004C8995980000004C89A5A00000004C89ADA80000004C89B5B00000004C89BDB8000000F20F1185C0000000F20F118DC8000000F20F1195D0000000F20F119DD8000000F20F11A5E0000000F20F11ADE8000000F20F11B5F0000000F20F11BDF8000000F2440F118500010000F2440F118D08010000F2440F119510010000F2440F119D18010000F2440F11A520010000F2440F11AD28010000F2440F11B530010000488B1C2508E6150348C7042500E615030000000048C7042508E615030000000048895D38584889452058488945104889E84C8BBC24880000004C8BB424800000004C8B6C24784C8B642470488B5C2468488B6C24604881C498000000C3 +[19c473e56f01] jit-backend-dump} +[19c473e58819] {jit-backend-dump BACKEND x86_64 -SYS_EXECUTABLE pypy -CODE_DUMP @29dd4436760 +0 4889455848894D60488955684889757048897D784C8985800000004C898D880000004C899590000000F20F1185C0000000F20F118DC8000000F20F1195D0000000F20F119DD8000000F20F11A5E0000000F20F11ADE8000000F20F11B5F0000000F20F11BDF8000000F2440F118500010000F2440F118D08010000F2440F119510010000F2440F119D18010000F2440F11A520010000F2440F11AD28010000F2440F11B530010000488B7C240849BBD01AD1CC9902000041FFD3488B4558488B4D60488B5568488B7570488B7D784C8B85800000004C8B8D880000004C8B9590000000F20F1085C0000000F20F108DC8000000F20F1095D0000000F20F109DD8000000F20F10A5E0000000F20F10ADE8000000F20F10B5F0000000F20F10BDF8000000F2440F108500010000F2440F108D08010000F2440F109510010000F2440F109D18010000F2440F10A520010000F2440F10AD28010000F2440F10B530010000C20800 -[d4bd45de666] jit-backend-dump} -[d4bd45e261c] {jit-backend-dump +SYS_EXECUTABLE python +CODE_DUMP @7fe7c97fa6bd +0 4889455848894D60488955684889757048897D784C8985800000004C898D880000004C899590000000F20F1185C0000000F20F118DC8000000F20F1195D0000000F20F119DD8000000F20F11A5E0000000F20F11ADE8000000F20F11B5F0000000F20F11BDF8000000F2440F118500010000F2440F118D08010000F2440F119510010000F2440F119D18010000F2440F11A520010000F2440F11AD28010000F2440F11B530010000488B7C240841BBB064120141FFD3488B4558488B4D60488B5568488B7570488B7D784C8B85800000004C8B8D880000004C8B9590000000F20F1085C0000000F20F108DC8000000F20F1095D0000000F20F109DD8000000F20F10A5E0000000F20F10ADE8000000F20F10B5F0000000F20F10BDF8000000F2440F108500010000F2440F108D08010000F2440F109510010000F2440F109D18010000F2440F10A520010000F2440F10AD28010000F2440F10B530010000C20800 +[19c473e5b9af] jit-backend-dump} +[19c473e5cf8d] {jit-backend-dump BACKEND x86_64 -SYS_EXECUTABLE pypy -CODE_DUMP @29dd44368c5 +0 4889455848894D60488955684889757048897D784C8985800000004C898D880000004C899590000000F20F1185C0000000F20F118DC8000000F20F1195D0000000F20F119DD8000000F20F11A5E0000000F20F11ADE8000000F20F11B5F0000000F20F11BDF8000000F2440F118500010000F2440F118D08010000F2440F119510010000F2440F119D18010000F2440F11A520010000F2440F11AD28010000F2440F11B530010000488B7C240849BB101CD1CC9902000041FFD3488B442408F6400480488B4558488B4D60488B5568488B7570488B7D784C8B85800000004C8B8D880000004C8B9590000000F20F1085C0000000F20F108DC8000000F20F1095D0000000F20F109DD8000000F20F10A5E0000000F20F10ADE8000000F20F10B5F0000000F20F10BDF8000000F2440F108500010000F2440F108D08010000F2440F109510010000F2440F109D18010000F2440F10A520010000F2440F10AD28010000F2440F10B530010000C20800 -[d4bd45f09fc] jit-backend-dump} -[d4bd45f4d26] {jit-backend-dump +SYS_EXECUTABLE python +CODE_DUMP @7fe7c97fa81e +0 4889455848894D60488955684889757048897D784C8985800000004C898D880000004C899590000000F20F1185C0000000F20F118DC8000000F20F1195D0000000F20F119DD8000000F20F11A5E0000000F20F11ADE8000000F20F11B5F0000000F20F11BDF8000000F2440F118500010000F2440F118D08010000F2440F119510010000F2440F119D18010000F2440F11A520010000F2440F11AD28010000F2440F11B530010000488B7C240841BBF065120141FFD3488B442408F6400480488B4558488B4D60488B5568488B7570488B7D784C8B85800000004C8B8D880000004C8B9590000000F20F1085C0000000F20F108DC8000000F20F1095D0000000F20F109DD8000000F20F10A5E0000000F20F10ADE8000000F20F10B5F0000000F20F10BDF8000000F2440F108500010000F2440F108D08010000F2440F109510010000F2440F109D18010000F2440F10A520010000F2440F10AD28010000F2440F10B530010000C20800 +[19c473e5fee0] jit-backend-dump} +[19c473e6101c] {jit-backend-dump BACKEND x86_64 -SYS_EXECUTABLE pypy -CODE_DUMP @29dd4436a33 +0 49BB48D3E5CE99020000498B0349BB40D3E5CE9902000049C7030000000049BB48D3E5CE9902000049C703000000004889453849BBE00A61CD990200004C895D104889E848BB30CF61CD9902000048832B084C8BBC24880000004C8BB424800000004C8B6C24784C8B642470488B5C2468488B6C24604881C498000000C3 -[d4bd45fbd0a] jit-backend-dump} -[d4bd46054f0] {jit-backend-dump +SYS_EXECUTABLE python +CODE_DUMP @7fe7c97fa988 +0 488B042508E6150348C7042500E615030000000048C7042508E61503000000004889453848C7451000C2B5014889E84C8BBC24880000004C8BB424800000004C8B6C24784C8B642470488B5C2468488B6C24604881C498000000C3 +[19c473e625e0] jit-backend-dump} +[19c473e68362] {jit-backend-dump BACKEND x86_64 -SYS_EXECUTABLE pypy -CODE_DUMP @29dd4436ab1 +0 48894D584889556848895D70488975784C8985880000004C898D900000004C8995980000004C89A5A00000004C89ADA80000004C89B5B00000004C89BDB8000000F20F1185C0000000F20F118DC8000000F20F1195D0000000F20F119DD8000000F20F11A5E0000000F20F11ADE8000000F20F11B5F0000000F20F11BDF8000000F2440F118500010000F2440F118D08010000F2440F119510010000F2440F119D18010000F2440F11A520010000F2440F11AD28010000F2440F11B530010000488B4C240848894D204883EC084829C749BB30A39FCC9902000041FFD34883C4084885C00F840201000049BB30CF61CD99020000498B0B488B69F8F645040174154883EC0849BB306243D49D02000041FFD34883C408488B4D58488B5568488B5D70488B75784C8B85880000004C8B8D900000004C8B95980000004C8BA5A00000004C8BADA80000004C8BB5B00000004C8BBDB8000000F20F1085C0000000F20F108DC8000000F20F1095D0000000F20F109DD8000000F20F10A5E0000000F20F10ADE8000000F20F10B5F0000000F20F10BDF8000000F2440F108500010000F2440F108D08010000F2440F109510010000F2440F109D18010000F2440F10A520010000F2440F10AD28010000F2440F10B53001000049BB28CE61CD99020000498B3B48C7452000000000C34883C40849BB336A43D49D02000041FFE3 -[d4bd461836e] jit-backend-dump} -[d4bd461e1f2] {jit-backend-dump +SYS_EXECUTABLE python +CODE_DUMP @7fe7c97fa9e3 +0 48894D584889556848895D70488975784C8985880000004C898D900000004C8995980000004C89A5A00000004C89ADA80000004C89B5B00000004C89BDB8000000F20F1185C0000000F20F118DC8000000F20F1195D0000000F20F119DD8000000F20F11A5E0000000F20F11ADE8000000F20F11B5F0000000F20F11BDF8000000F2440F118500010000F2440F118D08010000F2440F119510010000F2440F119D18010000F2440F11A520010000F2440F11AD28010000F2440F11B530010000488B4C240848894D204829C74883EC0848C745281000000041BBB0A4E80041FFD34883C4084885C00F84F4000000F645040174154883EC0849BBFDA17FC9E77F000041FFD34883C40848C7452800000000488B4D58488B5568488B5D70488B75784C8B85880000004C8B8D900000004C8B95980000004C8BA5A00000004C8BADA80000004C8BB5B00000004C8BBDB8000000F20F1085C0000000F20F108DC8000000F20F1095D0000000F20F109DD8000000F20F10A5E0000000F20F10ADE8000000F20F10B5F0000000F20F10BDF8000000F2440F108500010000F2440F108D08010000F2440F109510010000F2440F109D18010000F2440F10A520010000F2440F10AD28010000F2440F10B530010000488B3C25484CB60148C7452000000000C34883C40849BB88A97FC9E77F000041FFE3 +[19c473e6c488] jit-backend-dump} +[19c473e6ed0e] {jit-backend-dump BACKEND x86_64 -SYS_EXECUTABLE pypy -CODE_DUMP @29dd4436cae +0 48894D584889556848895D70488975784C8985880000004C898D900000004C8995980000004C89A5A00000004C89ADA80000004C89B5B00000004C89BDB8000000F20F1185C0000000F20F118DC8000000F20F1195D0000000F20F119DD8000000F20F11A5E0000000F20F11ADE8000000F20F11B5F0000000F20F11BDF8000000F2440F118500010000F2440F118D08010000F2440F119510010000F2440F119D18010000F2440F11A520010000F2440F11AD28010000F2440F11B530010000488B4C240848894D204883EC084889FA4889C6488B7C241849BB40A29FCC9902000041FFD34883C4084885C00F840201000049BB30CF61CD99020000498B0B488B69F8F645040174154883EC0849BB306243D49D02000041FFD34883C408488B4D58488B5568488B5D70488B75784C8B85880000004C8B8D900000004C8B95980000004C8BA5A00000004C8BADA80000004C8BB5B00000004C8BBDB8000000F20F1085C0000000F20F108DC8000000F20F1095D0000000F20F109DD8000000F20F10A5E0000000F20F10ADE8000000F20F10B5F0000000F20F10BDF8000000F2440F108500010000F2440F108D08010000F2440F109510010000F2440F109D18010000F2440F10A520010000F2440F10AD28010000F2440F10B53001000049BB28CE61CD99020000498B3B48C7452000000000C34883C40849BB336A43D49D02000041FFE3 -[d4bd4636ab0] jit-backend-dump} -[d4bd46401ae] {jit-backend-dump +SYS_EXECUTABLE python +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 pypy -CODE_DUMP @29dd4436eb3 +0 48894D584889556848895D70488975784C8985880000004C898D900000004C8995980000004C89A5A00000004C89ADA80000004C89B5B00000004C89BDB8000000F20F1185C0000000F20F118DC8000000F20F1195D0000000F20F119DD8000000F20F11A5E0000000F20F11ADE8000000F20F11B5F0000000F20F11BDF8000000F2440F118500010000F2440F118D08010000F2440F119510010000F2440F119D18010000F2440F11A520010000F2440F11AD28010000F2440F11B530010000488B4C240848894D204883EC0849BB00A39FCC9902000041FFD34883C4084885C00F840201000049BB30CF61CD99020000498B0B488B69F8F645040174154883EC0849BB306243D49D02000041FFD34883C408488B4D58488B5568488B5D70488B75784C8B85880000004C8B8D900000004C8B95980000004C8BA5A00000004C8BADA80000004C8BB5B00000004C8BBDB8000000F20F1085C0000000F20F108DC8000000F20F1095D0000000F20F109DD8000000F20F10A5E0000000F20F10ADE8000000F20F10B5F0000000F20F10BDF8000000F2440F108500010000F2440F108D08010000F2440F109510010000F2440F109D18010000F2440F10A520010000F2440F10AD28010000F2440F10B53001000049BB28CE61CD99020000498B3B48C7452000000000C34883C40849BB336A43D49D02000041FFE3 -[d4bd4653aa0] jit-backend-dump} -[d4bd465898a] {jit-backend-dump +SYS_EXECUTABLE python +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 pypy -CODE_DUMP @29dd44370ad +0 48894D584889556848895D70488975784C8985880000004C898D900000004C8995980000004C89A5A00000004C89ADA80000004C89B5B00000004C89BDB8000000F20F1185C0000000F20F118DC8000000F20F1195D0000000F20F119DD8000000F20F11A5E0000000F20F11ADE8000000F20F11B5F0000000F20F11BDF8000000F2440F118500010000F2440F118D08010000F2440F119510010000F2440F119D18010000F2440F11A520010000F2440F11AD28010000F2440F11B530010000488B4C240848894D204883EC0849BBD0A29FCC9902000041FFD34883C4084885C00F840201000049BB30CF61CD99020000498B0B488B69F8F645040174154883EC0849BB306243D49D02000041FFD34883C408488B4D58488B5568488B5D70488B75784C8B85880000004C8B8D900000004C8B95980000004C8BA5A00000004C8BADA80000004C8BB5B00000004C8BBDB8000000F20F1085C0000000F20F108DC8000000F20F1095D0000000F20F109DD8000000F20F10A5E0000000F20F10ADE8000000F20F10B5F0000000F20F10BDF8000000F2440F108500010000F2440F108D08010000F2440F109510010000F2440F109D18010000F2440F10A520010000F2440F10AD28010000F2440F10B53001000049BB28CE61CD99020000498B3B48C7452000000000C34883C40849BB336A43D49D02000041FFE3 -[d4bd466b5ba] jit-backend-dump} -[d4bd466f11c] {jit-backend-dump +SYS_EXECUTABLE python +CODE_DUMP @7fe7c97fadd6 +0 A1000000 +[19c474709e17] jit-backend-dump} +[19c47470a414] {jit-backend-dump BACKEND x86_64 -SYS_EXECUTABLE pypy -CODE_DUMP @29dd44372a7 +0 4889E74883EC0849BB40CEE3CC9902000041FFD34883C40849BB40D3E5CE99020000498B034885C07501C34883C40849BB336A43D49D02000041FFE3 -[d4bd4673ed6] jit-backend-dump} -[d4bd4674e24] {jit-backend-counts -[d4bd4675ab2] jit-backend-counts} -[d4bd590ac7a] {jit-backend -[d4bd5fccb60] {jit-backend-dump +SYS_EXECUTABLE python +CODE_DUMP @7fe7c97fade8 +0 B4000000 +[19c47470ae2a] jit-backend-dump} +[19c47470b293] {jit-backend-dump BACKEND x86_64 -SYS_EXECUTABLE pypy -CODE_DUMP @29dd4437450 +0 4881EC9800000048896C24604889FD48895C24684C896424704C896C24784C89B424800000004C89BC248800000049BB30CF61CD99020000498B1B48892B4883C30849891B49BB1867E6CE99020000498B034829E049BBE0E6ACCE99020000493B03760D49BBA77243D49D02000041FFD349BBD8401FD29D0200004D8B3B4D8D770149BBD8401FD29D0200004D89334C8BB5380100004D8B7E704D8B6E604D8B66784D8B96800000004D8B4E504D0FB6868E000000498B7E58498B7668488B5E10488B5618488B4620488B4E284C8995480100004C8B563048899D50010000488B5E3848898558010000488B46404C8995600100004C8B564848898568010000488B465048898570010000488B465848898578010000488B466048898580010000488B466848898588010000488B46704C8B76784C89B5900100004C8BB6800000004C89B5980100004C8BB6880000004C898DA00100004C8B8E9000000048898DA8010000488B8E9800000048898DB0010000488B8EA000000048898DB8010000488B8EA800000048898DC0010000488B8EB000000048898DC8010000488B8EB800000048898DD0010000488B8EC00000004C89ADD80100004C8BAEC80000004889BDE0010000488995E801000048899DF0010000488985F80100004C89B5000200004C898D0802000048898D100200004C89AD1802000049BBF0401FD29D0200004D8B2B498D4D0149BBF0401FD29D02000049890B4983FC0F0F85000000004C8BA59801000041813C2430EB00000F8500000000498B4C24104885C90F84000000004D8B6C24084C8B491041813990EA03000F85000000004C8B4908498B49084939CD0F8300000000498B49104E8B74E910498D4D0149894C24084983F8000F85000000004983FE000F85000000004C8B85780100004983F8017207418138902300000F85000000004D8B68084983FD000F85000000004983FA01720741813A902300000F850000000049BB0888C4D09D0200004D39DF0F85000000004D8B7A084983C7010F800000000049BBC066E6CE990200004D8B134983FA000F8C000000004C89B5E001000049BB08411FD29D0200004D8B334D8D460149BB08411FD29D0200004D89034D8B41084C39C10F83000000004D8B41104D8B74C8104C8D41014D894424084983FE000F85000000004C89F94983C7010F800000000049BBC066E6CE99020000498B0B4883F9000F8C000000004C89B5E00100004C89C1E986FFFFFF49BB1897C8D09D020000415349BB207343D49D020000415349BB006043D49D02000041FFE349BBF06254D39D020000415349BB307343D49D020000415349BB006043D49D02000041FFE349BB786254D39D020000415349BB407343D49D020000415349BB006043D49D02000041FFE349BB006254D39D020000415349BB507343D49D020000415349BB006043D49D02000041FFE349BB886154D39D020000415349BB607343D49D020000415349BB006043D49D02000041FFE349BB106154D39D020000415349BB707343D49D020000415349BB006043D49D02000041FFE349BB986054D39D020000415349BB807343D49D020000415349BB006043D49D02000041FFE349BB206054D39D020000415349BB907343D49D020000415349BB006043D49D02000041FFE349BB889FC8D09D020000415349BBA07343D49D020000415349BB006043D49D02000041FFE349BB109FC8D09D020000415349BBB07343D49D020000415349BB006043D49D02000041FFE349BB989EC8D09D020000415349BBC07343D49D020000415349BB006043D49D02000041FFE349BB209EC8D09D020000415349BBD07343D49D020000415349BB006043D49D02000041FFE349BBA89DC8D09D020000415349BBE07343D49D020000415349BB006043D49D02000041FFE349BB309DC8D09D020000415349BBF07343D49D020000415349BB006043D49D02000041FFE349BBB89CC8D09D020000415349BB007443D49D020000415349BB006043D49D02000041FFE349BB409CC8D09D020000415349BB107443D49D020000415349BB006043D49D02000041FFE349BBC89BC8D09D020000415349BB207443D49D020000415349BB006043D49D02000041FFE349BB509BC8D09D020000415349BB307443D49D020000415349BB006043D49D02000041FFE349BBD89AC8D09D020000415349BB407443D49D020000415349BB006043D49D02000041FFE3 -[d4bd6011706] jit-backend-dump} -[d4bd6013120] {jit-backend-addr -Loop 0 ( #274 FOR_ITER) has address 0x29dd44374c1 to 0x29dd44377d4 (bootstrap 0x29dd4437450) -[d4bd6016fb0] jit-backend-addr} -[d4bd6018af2] {jit-backend-dump +SYS_EXECUTABLE python +CODE_DUMP @7fe7c97fadf2 +0 CF000000 +[19c47470bc50] jit-backend-dump} +[19c47470c075] {jit-backend-dump BACKEND x86_64 -SYS_EXECUTABLE pypy -CODE_DUMP @29dd443766c +0 64010000 -[d4bd601be22] jit-backend-dump} -[d4bd601cec0] {jit-backend-dump +SYS_EXECUTABLE python +CODE_DUMP @7fe7c97fae05 +0 E1000000 +[19c47470c9b8] jit-backend-dump} +[19c47470cdc2] {jit-backend-dump BACKEND x86_64 -SYS_EXECUTABLE pypy -CODE_DUMP @29dd4437681 +0 74010000 -[d4bd601f6c4] jit-backend-dump} -[d4bd602088a] {jit-backend-dump +SYS_EXECUTABLE python +CODE_DUMP @7fe7c97fae16 +0 F5000000 +[19c47470d695] jit-backend-dump} +[19c47470dc77] {jit-backend-dump BACKEND x86_64 -SYS_EXECUTABLE pypy -CODE_DUMP @29dd443768f +0 8B010000 -[d4bd60230cc] jit-backend-dump} -[d4bd6024280] {jit-backend-dump +SYS_EXECUTABLE python +CODE_DUMP @7fe7c97fae2d +0 28010000 +[19c47470e564] jit-backend-dump} +[19c47470e995] {jit-backend-dump BACKEND x86_64 -SYS_EXECUTABLE pypy -CODE_DUMP @29dd44376a5 +0 9A010000 -[d4bd6026e72] jit-backend-dump} -[d4bd6027d12] {jit-backend-dump +SYS_EXECUTABLE python +CODE_DUMP @7fe7c97fae59 +0 21010000 +[19c47470f2a6] jit-backend-dump} +[19c47470f74a] {jit-backend-dump BACKEND x86_64 -SYS_EXECUTABLE pypy -CODE_DUMP @29dd44376b6 +0 AE010000 -[d4bd602b122] jit-backend-dump} -[d4bd602c1f6] {jit-backend-dump +SYS_EXECUTABLE python +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=) ++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: p16 = getfield_gc(p0, descr=) ++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] +debug_merge_point(0, 0, ' #12 LOAD_CONST') ++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] +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') +debug_merge_point(0, 0, ' #27 INPLACE_ADD') ++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(51804288, descr=) ++327: i29 = int_lt(i27, 0) +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(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] +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') +debug_merge_point(0, 0, ' #27 INPLACE_ADD') ++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(51804288, descr=) ++393: i34 = int_lt(i33, 0) +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(140633495988056)) ++411: --end of the loop-- +[19c4747929e2] jit-log-opt-loop} +[19c474a8bcae] {jit-backend +[19c474b8b379] {jit-backend-dump BACKEND x86_64 -SYS_EXECUTABLE pypy -CODE_DUMP @29dd44376d2 +0 B7010000 -[d4bd602eac2] jit-backend-dump} -[d4bd602fa20] {jit-backend-dump +SYS_EXECUTABLE python +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 pypy -CODE_DUMP @29dd44376dc +0 D2010000 -[d4bd603223e] jit-backend-dump} -[d4bd6033028] {jit-backend-dump +SYS_EXECUTABLE python +CODE_DUMP @7fe7c97fb1f6 +0 31010000 +[19c474ba1e7c] jit-backend-dump} +[19c474ba2395] {jit-backend-dump BACKEND x86_64 -SYS_EXECUTABLE pypy -CODE_DUMP @29dd44376f6 +0 DD010000 -[d4bd607b458] jit-backend-dump} -[d4bd607c918] {jit-backend-dump +SYS_EXECUTABLE python +CODE_DUMP @7fe7c97fb208 +0 44010000 +[19c474ba2cfc] jit-backend-dump} +[19c474ba314d] {jit-backend-dump BACKEND x86_64 -SYS_EXECUTABLE pypy -CODE_DUMP @29dd4437704 +0 F4010000 -[d4bd607f10c] jit-backend-dump} -[d4bd607ffd6] {jit-backend-dump +SYS_EXECUTABLE python +CODE_DUMP @7fe7c97fb212 +0 5F010000 +[19c474ba3a2b] jit-backend-dump} +[19c474ba3e5f] {jit-backend-dump BACKEND x86_64 -SYS_EXECUTABLE pypy -CODE_DUMP @29dd4437717 +0 06020000 -[d4bd6082502] jit-backend-dump} -[d4bd608348c] {jit-backend-dump +SYS_EXECUTABLE python +CODE_DUMP @7fe7c97fb225 +0 71010000 +[19c474ba4793] jit-backend-dump} +[19c474ba4bc7] {jit-backend-dump BACKEND x86_64 -SYS_EXECUTABLE pypy -CODE_DUMP @29dd443772a +0 18020000 -[d4bd6085a92] jit-backend-dump} -[d4bd6086a94] {jit-backend-dump +SYS_EXECUTABLE python +CODE_DUMP @7fe7c97fb236 +0 85010000 +[19c474ba5566] jit-backend-dump} +[19c474ba59a0] {jit-backend-dump BACKEND x86_64 -SYS_EXECUTABLE pypy -CODE_DUMP @29dd4437738 +0 2F020000 -[d4bd6089206] jit-backend-dump} -[d4bd608ab60] {jit-backend-dump +SYS_EXECUTABLE python +CODE_DUMP @7fe7c97fb24d +0 93010000 +[19c474ba62ae] jit-backend-dump} +[19c474ba66e1] {jit-backend-dump BACKEND x86_64 -SYS_EXECUTABLE pypy -CODE_DUMP @29dd443774f +0 62020000 -[d4bd608d342] jit-backend-dump} -[d4bd608e20e] {jit-backend-dump +SYS_EXECUTABLE python +CODE_DUMP @7fe7c97fb264 +0 A1010000 +[19c474ba6f81] jit-backend-dump} +[19c474ba7727] {jit-backend-dump BACKEND x86_64 -SYS_EXECUTABLE pypy -CODE_DUMP @29dd4437781 +0 55020000 -[d4bd6090ab6] jit-backend-dump} -[d4bd6091944] {jit-backend-dump +SYS_EXECUTABLE python +CODE_DUMP @7fe7c97fb2b8 +0 97010000 +[19c474ba801d] jit-backend-dump} +[19c474ba844b] {jit-backend-dump BACKEND x86_64 -SYS_EXECUTABLE pypy -CODE_DUMP @29dd443779d +0 5E020000 -[d4bd6093f98] jit-backend-dump} -[d4bd6094d3c] {jit-backend-dump +SYS_EXECUTABLE python +CODE_DUMP @7fe7c97fb2c6 +0 AE010000 +[19c474ba8d0e] jit-backend-dump} +[19c474ba91df] {jit-backend-dump BACKEND x86_64 -SYS_EXECUTABLE pypy -CODE_DUMP @29dd44377aa +0 76020000 -[d4bd609738e] jit-backend-dump} -[d4bd6098392] {jit-backend-dump +SYS_EXECUTABLE python +CODE_DUMP @7fe7c97fb2dd +0 E1010000 +[19c474ba9a8b] jit-backend-dump} +[19c474ba9ece] {jit-backend-dump BACKEND x86_64 -SYS_EXECUTABLE pypy -CODE_DUMP @29dd44377c1 +0 A9020000 -[d4bd609ab48] jit-backend-dump} -[d4bd609d80a] jit-backend} -[d4bd60a2c66] {jit-log-opt-loop -# Loop 0 ( #274 FOR_ITER) : loop with 106 ops +SYS_EXECUTABLE python +CODE_DUMP @7fe7c97fb309 +0 DA010000 +[19c474baa811] jit-backend-dump} +[19c474baac68] {jit-backend-dump +BACKEND x86_64 +SYS_EXECUTABLE python +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] -+143: p2 = getfield_gc(p0, descr=) -+154: p3 = getfield_gc(p0, descr=) -+158: i4 = getfield_gc(p0, descr=) -+162: p5 = getfield_gc(p0, descr=) -+169: p6 = getfield_gc(p0, descr=) -+173: i7 = getfield_gc(p0, descr=) -+181: i8 = getfield_gc(p0, descr=) -+185: p9 = getfield_gc(p0, descr=) -+189: p11 = getarrayitem_gc(p9, 0, descr=) -+193: p13 = getarrayitem_gc(p9, 1, descr=) -+197: p15 = getarrayitem_gc(p9, 2, descr=) -+201: p17 = getarrayitem_gc(p9, 3, descr=) -+205: p19 = getarrayitem_gc(p9, 4, descr=) -+216: p21 = getarrayitem_gc(p9, 5, descr=) -+227: p23 = getarrayitem_gc(p9, 6, descr=) -+238: p25 = getarrayitem_gc(p9, 7, descr=) -+249: p27 = getarrayitem_gc(p9, 8, descr=) -+260: p29 = getarrayitem_gc(p9, 9, descr=) -+271: p31 = getarrayitem_gc(p9, 10, descr=) -+282: p33 = getarrayitem_gc(p9, 11, descr=) -+293: p35 = getarrayitem_gc(p9, 12, descr=) -+304: p37 = getarrayitem_gc(p9, 13, descr=) -+308: p39 = getarrayitem_gc(p9, 14, descr=) -+322: p41 = getarrayitem_gc(p9, 15, descr=) -+336: p43 = getarrayitem_gc(p9, 16, descr=) -+350: p45 = getarrayitem_gc(p9, 17, descr=) -+364: p47 = getarrayitem_gc(p9, 18, descr=) -+378: p49 = getarrayitem_gc(p9, 19, descr=) -+392: p51 = getarrayitem_gc(p9, 20, descr=) -+406: p53 = getarrayitem_gc(p9, 21, descr=) -+420: p55 = getarrayitem_gc(p9, 22, descr=) -+434: p57 = getarrayitem_gc(p9, 23, descr=) -+448: p58 = getfield_gc(p0, descr=) -+448: label(p0, p1, p2, p3, i4, p5, p6, i7, i8, p11, p13, p15, p17, p19, p21, p23, p25, p27, p29, p31, p33, p35, p37, p39, p41, p43, p45, p47, p49, p51, p53, p55, p57, descr=TargetToken(2876835872976)) -debug_merge_point(0, 0, ' #274 FOR_ITER') -+534: guard_value(i4, 15, descr=) [i4, p1, p0, p2, p3, p5, p6, i7, i8, p11, p13, p15, p17, p19, p21, p23, p25, p27, p29, p31, p33, p35, p37, p39, p41, p43, p45, p47, p49, p51, p53, p55, p57] -+544: guard_class(p39, 2859595984528, descr=) [p1, p0, p39, p2, p3, p5, p6, i7, p11, p13, p15, p17, p19, p21, p23, p25, p27, p29, p31, p33, p35, p37, p41, p43, p45, p47, p49, p51, p53, p55, p57] -+565: p61 = getfield_gc(p39, descr=) -+570: guard_nonnull(p61, descr=) [p1, p0, p39, p61, p2, p3, p5, p6, i7, p11, p13, p15, p17, p19, p21, p23, p25, p27, p29, p31, p33, p35, p37, p41, p43, p45, p47, p49, p51, p53, p55, p57] -+579: i62 = getfield_gc(p39, descr=) -+584: p63 = getfield_gc(p61, descr=) -+588: guard_class(p63, 2859596180976, descr=) [p1, p0, p39, i62, p63, p61, p2, p3, p5, p6, i7, p11, p13, p15, p17, p19, p21, p23, p25, p27, p29, p31, p33, p35, p37, p41, p43, p45, p47, p49, p51, p53, p55, p57] -+601: p65 = getfield_gc(p61, descr=) -+605: i66 = getfield_gc(p65, descr=) -+609: i67 = uint_ge(i62, i66) -guard_false(i67, descr=) [p1, p0, p39, i62, i66, p65, p2, p3, p5, p6, i7, p11, p13, p15, p17, p19, p21, p23, p25, p27, p29, p31, p33, p35, p37, p41, p43, p45, p47, p49, p51, p53, p55, p57] -+618: p68 = getfield_gc(p65, descr=) -+622: i69 = getarrayitem_gc(p68, i62, descr=) -+627: i71 = int_add(i62, 1) -+631: setfield_gc(p39, i71, descr=) -+636: guard_value(i7, 0, descr=) [i7, p1, p0, p2, p3, p5, p6, p11, p13, p15, p17, p19, p21, p23, p25, p27, p29, p31, p33, p35, p37, p39, p43, p45, p47, p49, p51, p53, p55, p57, i69] -debug_merge_point(0, 0, ' #277 STORE_FAST') -debug_merge_point(0, 0, ' #280 LOAD_FAST') -debug_merge_point(0, 0, ' #283 POP_JUMP_IF_FALSE') -+646: i73 = int_is_true(i69) -guard_false(i73, descr=) [p1, p0, p2, p3, p5, p6, p11, p13, p15, p17, p19, p21, p23, p25, p27, p29, p31, p33, p37, p39, p43, p45, p47, p49, p51, p53, p55, p57, i69] -debug_merge_point(0, 0, ' #320 LOAD_FAST') -+656: guard_nonnull_class(p29, ConstClass(W_IntObject), descr=) [p1, p0, p29, p2, p3, p5, p6, p11, p13, p15, p17, p19, p21, p23, p25, p27, p31, p33, p37, p39, p43, p45, p47, p49, p51, p53, p55, p57, i69] -debug_merge_point(0, 0, ' #323 POP_JUMP_IF_FALSE') -+682: i75 = getfield_gc_pure(p29, descr=) -+686: i76 = int_is_true(i75) -guard_false(i76, descr=) [p1, p0, p29, p2, p3, p5, p6, p11, p13, p15, p17, p19, p21, p23, p25, p27, p31, p33, p37, p39, p43, p45, p47, p49, p51, p53, p55, p57, i69] -debug_merge_point(0, 0, ' #351 LOAD_FAST') -+696: guard_nonnull_class(p25, ConstClass(W_IntObject), descr=) [p1, p0, p25, p2, p3, p5, p6, p11, p13, p15, p17, p19, p21, p23, p27, p29, p31, p33, p37, p39, p43, p45, p47, p49, p51, p53, p55, p57, i69] -debug_merge_point(0, 0, ' #354 LOAD_CONST') -+715: guard_value(p2, ConstPtr(ptr78), descr=) [p1, p0, p2, p3, p5, p6, p11, p13, p15, p17, p19, p21, p23, p25, p27, p29, p31, p33, p37, p39, p43, p45, p47, p49, p51, p53, p55, p57, i69] -debug_merge_point(0, 0, ' #357 BINARY_ADD') -+734: i79 = getfield_gc_pure(p25, descr=) -+738: i81 = int_add_ovf(i79, 1) -guard_no_overflow(descr=) [p1, p0, p25, i81, p3, p5, p6, p11, p13, p15, p17, p19, p21, p23, p27, p29, p31, p33, p37, p39, p45, p47, p49, p51, p53, p55, p57, i69] -debug_merge_point(0, 0, ' #358 STORE_FAST') -debug_merge_point(0, 0, ' #361 JUMP_ABSOLUTE') -+748: guard_not_invalidated(descr=) [p1, p0, p3, p5, p6, p11, p13, p15, p17, p19, p21, p23, p27, p29, p31, p33, p37, p39, p45, p47, p49, p51, p53, p55, p57, i81, i69] -+748: i83 = getfield_raw(2859624457920, descr=) -+761: i85 = int_lt(i83, 0) -guard_false(i85, descr=) [p1, p0, p3, p5, p6, p11, p13, p15, p17, p19, p21, p23, p27, p29, p31, p33, p37, p39, p45, p47, p49, p51, p53, p55, p57, i81, i69] -debug_merge_point(0, 0, ' #274 FOR_ITER') -+771: label(p0, p1, p3, p5, p6, p11, p13, p15, p17, p19, p21, p23, i81, p27, p29, p31, p33, i69, p37, p39, p45, p47, p49, p51, p53, p55, p57, p65, i71, descr=TargetToken(2876835873064)) -debug_merge_point(0, 0, ' #274 FOR_ITER') -+808: i86 = getfield_gc(p65, descr=) -+812: i87 = uint_ge(i71, i86) -guard_false(i87, descr=) [p1, p0, p39, i71, i86, p65, p3, p5, p6, p11, p13, p15, p17, p19, p21, p23, p27, p29, p31, p33, p37, p45, p47, p49, p51, p53, p55, p57, i81, i69] -+821: p88 = getfield_gc(p65, descr=) -+825: i89 = getarrayitem_gc(p88, i71, descr=) -+830: i90 = int_add(i71, 1) -debug_merge_point(0, 0, ' #277 STORE_FAST') -debug_merge_point(0, 0, ' #280 LOAD_FAST') -debug_merge_point(0, 0, ' #283 POP_JUMP_IF_FALSE') -+834: setfield_gc(p39, i90, descr=) -+839: i91 = int_is_true(i89) -guard_false(i91, descr=) [p1, p0, p3, p5, p6, p11, p13, p15, p17, p19, p21, p23, p27, p29, p31, p33, p37, p39, p45, p47, p49, p51, p53, p55, p57, i89, i81, None] -debug_merge_point(0, 0, ' #320 LOAD_FAST') -debug_merge_point(0, 0, ' #323 POP_JUMP_IF_FALSE') -debug_merge_point(0, 0, ' #351 LOAD_FAST') -debug_merge_point(0, 0, ' #354 LOAD_CONST') -debug_merge_point(0, 0, ' #357 BINARY_ADD') -+849: i93 = int_add_ovf(i81, 1) -guard_no_overflow(descr=) [p1, p0, i93, p3, p5, p6, p11, p13, p15, p17, p19, p21, p23, p27, p29, p31, p33, p37, p39, p45, p47, p49, p51, p53, p55, p57, i89, i81, None] -debug_merge_point(0, 0, ' #358 STORE_FAST') -debug_merge_point(0, 0, ' #361 JUMP_ABSOLUTE') -+862: guard_not_invalidated(descr=) [p1, p0, p3, p5, p6, p11, p13, p15, p17, p19, p21, p23, p27, p29, p31, p33, p37, p39, p45, p47, p49, p51, p53, p55, p57, i93, i89, None, None] -+862: i94 = getfield_raw(2859624457920, descr=) -+875: i95 = int_lt(i94, 0) -guard_false(i95, descr=) [p1, p0, p3, p5, p6, p11, p13, p15, p17, p19, p21, p23, p27, p29, p31, p33, p37, p39, p45, p47, p49, p51, p53, p55, p57, i93, i89, None, None] -debug_merge_point(0, 0, ' #274 FOR_ITER') -+885: jump(p0, p1, p3, p5, p6, p11, p13, p15, p17, p19, p21, p23, i93, p27, p29, p31, p33, i89, p37, p39, p45, p47, p49, p51, p53, p55, p57, p65, i90, descr=TargetToken(2876835873064)) -+900: --end of the loop-- -[d4bd632bb1a] jit-log-opt-loop} -[d4bd75888aa] {jit-backend -[d4bd786b446] {jit-backend-dump ++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: p16 = getfield_gc(p0, descr=) ++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] +debug_merge_point(0, 0, ' #12 LOAD_CONST') ++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] +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] ++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] +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] ++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] +debug_merge_point(1, 1, ' #0 LOAD_FAST') +debug_merge_point(1, 1, ' #3 LOAD_CONST') +debug_merge_point(1, 1, ' #6 BINARY_ADD') ++458: i36 = int_add(i21, 1) +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(51804288, descr=) ++471: i41 = int_lt(i39, 0) +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(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] +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] +debug_merge_point(0, 0, ' #24 LOAD_FAST') +debug_merge_point(0, 0, ' #27 CALL_FUNCTION') ++525: p44 = force_token() +debug_merge_point(1, 1, ' #0 LOAD_FAST') +debug_merge_point(1, 1, ' #3 LOAD_CONST') +debug_merge_point(1, 1, ' #6 BINARY_ADD') ++525: i45 = int_add(i36, 1) +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(51804288, descr=) ++537: i47 = int_lt(i46, 0) +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(140633495988848)) ++555: --end of the loop-- +[19c474bf9fca] jit-log-opt-loop} +[19c474c0e8bc] {jit-backend-dump BACKEND x86_64 -SYS_EXECUTABLE pypy -CODE_DUMP @29dd4437bc8 +0 48817D50FFFFFF007D2448C7442408FFFFFF0049BB987A43D49D0200004C891C2449BBCA6243D49D02000041FFD349BBC0401FD29D0200004D8B2B4D8D4D0149BBC0401FD29D0200004D890B4C8B8D780100004983F9017207418139902300000F850000000049BB0888C4D09D0200004D39DF0F85000000004D8B79084983FF000F84000000004983C7010F80000000004983FA01720741813A902300000F85000000004D8B4A084983C1010F800000000049BBC066E6CE990200004D8B134983FA000F8C000000004C89B57801000049BB20411FD29D0200004D8B334D8D560149BB20411FD29D0200004D891341813C2430EB00000F85000000004D8B5424104D85D20F84000000004D8B7424084D8B6A1041817D0090EA03000F85000000004D8B6A084D8B55084D39D60F83000000004D8B55104F8B6CF2104D8D56014D895424084983FD000F84000000004983FF000F84000000004D89FA4983C7010F80000000004D89CA4983C1010F800000000049BBC066E6CE990200004D8B134983FA000F8C000000004C89AD78010000E93BFFFFFF49BB306E54D39D020000415349BBA87A43D49D020000415349BB006043D49D02000041FFE349BB907754D39D020000415349BBB87A43D49D020000415349BB006043D49D02000041FFE349BB187754D39D020000415349BBC87A43D49D020000415349BB006043D49D02000041FFE349BBA07654D39D020000415349BBD87A43D49D020000415349BB006043D49D02000041FFE349BB287654D39D020000415349BBE87A43D49D020000415349BB006043D49D02000041FFE349BBB07554D39D020000415349BBF87A43D49D020000415349BB006043D49D02000041FFE349BB387554D39D020000415349BB087B43D49D020000415349BB006043D49D02000041FFE349BBC07454D39D020000415349BB187B43D49D020000415349BB006043D49D02000041FFE349BB487454D39D020000415349BB287B43D49D020000415349BB006043D49D02000041FFE349BBD07354D39D020000415349BB387B43D49D020000415349BB006043D49D02000041FFE349BB587354D39D020000415349BB487B43D49D020000415349BB006043D49D02000041FFE349BBE07254D39D020000415349BB587B43D49D020000415349BB006043D49D02000041FFE349BB687254D39D020000415349BB687B43D49D020000415349BB006043D49D02000041FFE349BBF07154D39D020000415349BB787B43D49D020000415349BB006043D49D02000041FFE349BB787154D39D020000415349BB887B43D49D020000415349BB006043D49D02000041FFE349BB007154D39D020000415349BB987B43D49D020000415349BB006043D49D02000041FFE349BB887054D39D020000415349BBA87B43D49D020000415349BB006043D49D02000041FFE349BB107054D39D020000415349BBB87B43D49D020000415349BB006043D49D02000041FFE3 -[d4bd78951be] jit-backend-dump} -[d4bd7897294] {jit-backend-dump +SYS_EXECUTABLE python +CODE_DUMP @7fe7c97fb268 +0 E9C1010000 +[19c474c103d6] jit-backend-dump} +[19c474c10960] {jit-backend-dump BACKEND x86_64 -SYS_EXECUTABLE pypy -CODE_DUMP @29dd4437bcc +0 39000000 -[d4bd789a7de] jit-backend-dump} -[d4bd789b93c] {jit-backend-dump +SYS_EXECUTABLE python +CODE_DUMP @7fe7c97fb2cf +0 E9C9010000 +[19c474c1148a] jit-backend-dump} +[19c474c118f3] {jit-backend-dump BACKEND x86_64 -SYS_EXECUTABLE pypy -CODE_DUMP @29dd4437bd7 +0 39000000 -[d4bd789e688] jit-backend-dump} -[d4bd789f6be] {jit-backend-addr -bridge out of Guard 0x29dd3546098 has address 0x29dd4437bc8 to 0x29dd4437d5d -[d4bd78a1f78] jit-backend-addr} -[d4bd78a3324] {jit-backend-dump +SYS_EXECUTABLE python +CODE_DUMP @7fe7c97fb30d +0 E9FA010000 +[19c474c122f5] jit-backend-dump} +[19c47509a4c2] {jit-backend +[19c475193ba8] {jit-backend-dump BACKEND x86_64 -SYS_EXECUTABLE pypy -CODE_DUMP @29dd4437c2a +0 2F010000 -[d4bd78a62e8] jit-backend-dump} -[d4bd78a719a] {jit-backend-dump +SYS_EXECUTABLE python +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 pypy -CODE_DUMP @29dd4437c3d +0 41010000 -[d4bd78aa178] jit-backend-dump} -[d4bd78ab206] {jit-backend-dump +SYS_EXECUTABLE python +CODE_DUMP @7fe7c97fb76d +0 27010000 +[19c4751aef16] jit-backend-dump} +[19c4751af4c9] {jit-backend-dump BACKEND x86_64 -SYS_EXECUTABLE pypy -CODE_DUMP @29dd4437c4b +0 58010000 -[d4bd78adb80] jit-backend-dump} -[d4bd78aea3a] {jit-backend-dump +SYS_EXECUTABLE python +CODE_DUMP @7fe7c97fb779 +0 40010000 +[19c4751aff5c] jit-backend-dump} +[19c4751b03b0] {jit-backend-dump BACKEND x86_64 -SYS_EXECUTABLE pypy -CODE_DUMP @29dd4437c55 +0 73010000 -[d4bd78b15ee] jit-backend-dump} -[d4bd78b2378] {jit-backend-dump +SYS_EXECUTABLE python +CODE_DUMP @7fe7c97fb786 +0 58010000 +[19c4751b0dcc] jit-backend-dump} +[19c4751b122c] {jit-backend-dump BACKEND x86_64 -SYS_EXECUTABLE pypy -CODE_DUMP @29dd4437c68 +0 85010000 -[d4bd78d5c42] jit-backend-dump} -[d4bd78d6e8a] {jit-backend-dump +SYS_EXECUTABLE python +CODE_DUMP @7fe7c97fb79c +0 67010000 +[19c4751b1b28] jit-backend-dump} +[19c4751b2047] {jit-backend-dump BACKEND x86_64 -SYS_EXECUTABLE pypy -CODE_DUMP @29dd4437c76 +0 9C010000 -[d4bd78d9522] jit-backend-dump} -[d4bd78daa16] {jit-backend-dump +SYS_EXECUTABLE python +CODE_DUMP @7fe7c97fb7b6 +0 72010000 +[19c4751b2928] jit-backend-dump} +[19c4751b2d6d] {jit-backend-dump BACKEND x86_64 -SYS_EXECUTABLE pypy -CODE_DUMP @29dd4437c8d +0 CF010000 -[d4bd78dd08c] jit-backend-dump} -[d4bd78de098] {jit-backend-dump +SYS_EXECUTABLE python +CODE_DUMP @7fe7c97fb7bf +0 8E010000 +[19c4751b36fb] jit-backend-dump} +[19c4751b3b61] {jit-backend-dump BACKEND x86_64 -SYS_EXECUTABLE pypy -CODE_DUMP @29dd4437cc0 +0 C1010000 -[d4bd78e08ea] jit-backend-dump} -[d4bd78e195e] {jit-backend-dump +SYS_EXECUTABLE python +CODE_DUMP @7fe7c97fb7de +0 94010000 +[19c4751b440d] jit-backend-dump} +[19c4751b4852] {jit-backend-dump BACKEND x86_64 -SYS_EXECUTABLE pypy -CODE_DUMP @29dd4437cce +0 D8010000 -[d4bd78e4102] jit-backend-dump} -[d4bd78e4f9a] {jit-backend-dump +SYS_EXECUTABLE python +CODE_DUMP @7fe7c97fb7f0 +0 A7010000 +[19c4751b5192] jit-backend-dump} +[19c4751b55cc] {jit-backend-dump BACKEND x86_64 -SYS_EXECUTABLE pypy -CODE_DUMP @29dd4437ce5 +0 E6010000 -[d4bd78e791a] jit-backend-dump} -[d4bd78e87b2] {jit-backend-dump +SYS_EXECUTABLE python +CODE_DUMP @7fe7c97fb803 +0 B9010000 +[19c4751b5ead] jit-backend-dump} +[19c4751b6304] {jit-backend-dump BACKEND x86_64 -SYS_EXECUTABLE pypy -CODE_DUMP @29dd4437cf6 +0 FA010000 -[d4bd78eae38] jit-backend-dump} -[d4bd78ebc12] {jit-backend-dump +SYS_EXECUTABLE python +CODE_DUMP @7fe7c97fb811 +0 D0010000 +[19c4751b6baa] jit-backend-dump} +[19c4751b71bc] {jit-backend-dump BACKEND x86_64 -SYS_EXECUTABLE pypy -CODE_DUMP @29dd4437d12 +0 03020000 -[d4bd78ee1fc] jit-backend-dump} -[d4bd78eef7e] {jit-backend-dump +SYS_EXECUTABLE python +CODE_DUMP @7fe7c97fb823 +0 08020000 +[19c4751b7aa9] jit-backend-dump} +[19c4751b7ec5] {jit-backend-dump BACKEND x86_64 -SYS_EXECUTABLE pypy -CODE_DUMP @29dd4437d1c +0 1E020000 -[d4bd78f151a] jit-backend-dump} -[d4bd78f234a] {jit-backend-dump +SYS_EXECUTABLE python +CODE_DUMP @7fe7c97fb851 +0 FF010000 +[19c4751b87ca] jit-backend-dump} +[19c4751b8c15] {jit-backend-dump BACKEND x86_64 -SYS_EXECUTABLE pypy -CODE_DUMP @29dd4437d29 +0 36020000 -[d4bd78f4830] jit-backend-dump} -[d4bd78f5634] {jit-backend-dump +SYS_EXECUTABLE python +CODE_DUMP @7fe7c97fb873 +0 02020000 +[19c4751b94d6] jit-backend-dump} +[19c4751b99a7] {jit-backend-dump BACKEND x86_64 -SYS_EXECUTABLE pypy -CODE_DUMP @29dd4437d36 +0 4E020000 -[d4bd78fc806] jit-backend-dump} -[d4bd78fd812] {jit-backend-dump +SYS_EXECUTABLE python +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=) ++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: 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(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] ++277: p23 = getfield_gc(p15, descr=) ++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] ++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') ++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] +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] +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: 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') ++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] ++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') ++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') ++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') ++545: jump(p0, p1, p2, p3, p6, i52, i50, p15, i51, i30, i29, i28, descr=TargetToken(140633495989464)) ++560: --end of the loop-- +[19c475204f61] jit-log-opt-loop} +[19c47566fb6c] {jit-backend +[19c47596b738] {jit-backend-dump BACKEND x86_64 -SYS_EXECUTABLE pypy -CODE_DUMP @29dd4437d4d +0 81020000 -[d4bd78ffeb2] jit-backend-dump} -[d4bd79011dc] {jit-backend-dump +SYS_EXECUTABLE python +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 pypy -CODE_DUMP @29dd44376dc +0 E8040000 -[d4bd7903838] jit-backend-dump} -[d4bd790546a] jit-backend} -[d4bd7909618] {jit-log-opt-bridge -# bridge out of Guard 0x29dd3546098 with 76 ops -[p0, p1, p2, p3, p4, p5, p6, p7, p8, p9, p10, p11, p12, p13, p14, p15, p16, p17, p18, p19, p20, p21, p22, p23, p24, p25, p26, p27, i28] -debug_merge_point(0, 0, ' #286 LOAD_FAST') -+76: guard_nonnull_class(p15, ConstClass(W_IntObject), descr=) [p0, p1, p15, p2, p3, p4, p5, p6, p7, p8, p9, p10, p11, p12, p13, p14, p16, p17, p18, p19, p20, p21, p22, p23, p24, p25, p26, p27, i28] -debug_merge_point(0, 0, ' #289 LOAD_CONST') -+102: guard_value(p2, ConstPtr(ptr30), descr=) [p0, p1, p2, p3, p4, p5, p6, p7, p8, p9, p10, p11, p12, p13, p14, p15, p16, p17, p18, p19, p20, p21, p22, p23, p24, p25, p26, p27, i28] -debug_merge_point(0, 0, ' #292 COMPARE_OP') -+121: i31 = getfield_gc_pure(p15, descr=) -+125: i33 = int_eq(i31, 0) -guard_false(i33, descr=) [p0, p1, p15, p3, p4, p5, p6, p7, p8, p9, p10, p11, p12, p13, p14, p16, p17, p18, p19, p21, p22, p23, p24, p25, p26, p27, i28] -debug_merge_point(0, 0, ' #295 POP_JUMP_IF_FALSE') -debug_merge_point(0, 0, ' #307 LOAD_FAST') -debug_merge_point(0, 0, ' #310 LOAD_CONST') -debug_merge_point(0, 0, ' #313 BINARY_ADD') -+135: i35 = int_add_ovf(i31, 1) -guard_no_overflow(descr=) [p0, p1, p15, i35, p3, p4, p5, p6, p7, p8, p9, p10, p11, p12, p13, p14, p16, p17, p18, p19, p21, p22, p23, p24, p25, p26, p27, i28] -debug_merge_point(0, 0, ' #314 STORE_FAST') -debug_merge_point(0, 0, ' #317 JUMP_FORWARD') -debug_merge_point(0, 0, ' #351 LOAD_FAST') -+145: guard_nonnull_class(p13, ConstClass(W_IntObject), descr=) [p0, p1, p13, p3, p4, p5, p6, p7, p8, p9, p10, p11, p12, p14, p16, p17, p18, p19, p21, p22, p23, p24, p25, p26, p27, i35, i28] -debug_merge_point(0, 0, ' #354 LOAD_CONST') -debug_merge_point(0, 0, ' #357 BINARY_ADD') -+164: i37 = getfield_gc_pure(p13, descr=) -+168: i39 = int_add_ovf(i37, 1) -guard_no_overflow(descr=) [p0, p1, p13, i39, p3, p4, p5, p6, p7, p8, p9, p10, p11, p12, p14, p16, p17, p18, p19, p21, p22, p23, p24, p25, p26, p27, i35, i28] -debug_merge_point(0, 0, ' #358 STORE_FAST') -debug_merge_point(0, 0, ' #361 JUMP_ABSOLUTE') -+178: guard_not_invalidated(descr=) [p0, p1, p3, p4, p5, p6, p7, p8, p9, p10, p11, p12, p14, p16, p17, p18, p19, p21, p22, p23, p24, p25, p26, p27, i39, i35, i28] -+178: i41 = getfield_raw(2859624457920, descr=) -+191: i43 = int_lt(i41, 0) -guard_false(i43, descr=) [p0, p1, p3, p4, p5, p6, p7, p8, p9, p10, p11, p12, p14, p16, p17, p18, p19, p21, p22, p23, p24, p25, p26, p27, i39, i35, i28] -debug_merge_point(0, 0, ' #274 FOR_ITER') -+201: label(p1, p0, p3, p4, p5, p6, p7, p8, p9, p10, p11, p12, i39, p14, i35, p16, p17, i28, p18, p19, p21, p22, p23, p24, p25, p26, p27, descr=TargetToken(2876835874912)) -+238: guard_class(p19, 2859595984528, descr=) [p0, p1, p19, p3, p4, p5, p6, p7, p8, p9, p10, p11, p12, p14, p16, p17, p18, p21, p22, p23, p24, p25, p26, p27, i35, i28, i39] -+252: p45 = getfield_gc(p19, descr=) -+257: guard_nonnull(p45, descr=) [p0, p1, p19, p45, p3, p4, p5, p6, p7, p8, p9, p10, p11, p12, p14, p16, p17, p18, p21, p22, p23, p24, p25, p26, p27, i35, i28, i39] -+266: i46 = getfield_gc(p19, descr=) -+271: p47 = getfield_gc(p45, descr=) -+275: guard_class(p47, 2859596180976, descr=) [p0, p1, p19, i46, p47, p45, p3, p4, p5, p6, p7, p8, p9, p10, p11, p12, p14, p16, p17, p18, p21, p22, p23, p24, p25, p26, p27, i35, i28, i39] -+289: p49 = getfield_gc(p45, descr=) -+293: i50 = getfield_gc(p49, descr=) -+297: i51 = uint_ge(i46, i50) -guard_false(i51, descr=) [p0, p1, p19, i46, i50, p49, p3, p4, p5, p6, p7, p8, p9, p10, p11, p12, p14, p16, p17, p18, p21, p22, p23, p24, p25, p26, p27, i35, i28, i39] -+306: p52 = getfield_gc(p49, descr=) -+310: i53 = getarrayitem_gc(p52, i46, descr=) -+315: i55 = int_add(i46, 1) -debug_merge_point(0, 0, ' #277 STORE_FAST') -debug_merge_point(0, 0, ' #280 LOAD_FAST') -debug_merge_point(0, 0, ' #283 POP_JUMP_IF_FALSE') -+319: setfield_gc(p19, i55, descr=) -+324: i56 = int_is_true(i53) -guard_true(i56, descr=) [p0, p1, p3, p4, p5, p6, p7, p8, p9, p10, p11, p12, p14, p16, p17, p18, p19, p21, p22, p23, p24, p25, p26, p27, i53, i35, None, i39] -debug_merge_point(0, 0, ' #286 LOAD_FAST') -debug_merge_point(0, 0, ' #289 LOAD_CONST') -debug_merge_point(0, 0, ' #292 COMPARE_OP') -+334: i59 = int_eq(i35, 0) -guard_false(i59, descr=) [p0, p1, p3, p4, p5, p6, p7, p8, p9, p10, p11, p12, p14, p16, p17, p18, p19, p21, p22, p23, p24, p25, p26, p27, i53, i35, None, i39] -debug_merge_point(0, 0, ' #295 POP_JUMP_IF_FALSE') -debug_merge_point(0, 0, ' #307 LOAD_FAST') -debug_merge_point(0, 0, ' #310 LOAD_CONST') -debug_merge_point(0, 0, ' #313 BINARY_ADD') -+344: i61 = int_add_ovf(i35, 1) -guard_no_overflow(descr=) [p0, p1, i61, p3, p4, p5, p6, p7, p8, p9, p10, p11, p12, p14, p16, p17, p18, p19, p21, p22, p23, p24, p25, p26, p27, i53, i35, None, i39] -debug_merge_point(0, 0, ' #314 STORE_FAST') -debug_merge_point(0, 0, ' #317 JUMP_FORWARD') -debug_merge_point(0, 0, ' #351 LOAD_FAST') -debug_merge_point(0, 0, ' #354 LOAD_CONST') -debug_merge_point(0, 0, ' #357 BINARY_ADD') -+357: i63 = int_add_ovf(i39, 1) -guard_no_overflow(descr=) [p0, p1, i63, p3, p4, p5, p6, p7, p8, p9, p10, p11, p12, p14, p16, p17, p18, p19, p21, p22, p23, p24, p25, p26, p27, i61, i53, None, None, i39] -debug_merge_point(0, 0, ' #358 STORE_FAST') -debug_merge_point(0, 0, ' #361 JUMP_ABSOLUTE') -+370: guard_not_invalidated(descr=) [p0, p1, p3, p4, p5, p6, p7, p8, p9, p10, p11, p12, p14, p16, p17, p18, p19, p21, p22, p23, p24, p25, p26, p27, i63, i61, i53, None, None, None] -+370: i65 = getfield_raw(2859624457920, descr=) -+383: i67 = int_lt(i65, 0) -guard_false(i67, descr=) [p0, p1, p3, p4, p5, p6, p7, p8, p9, p10, p11, p12, p14, p16, p17, p18, p19, p21, p22, p23, p24, p25, p26, p27, i63, i61, i53, None, None, None] -debug_merge_point(0, 0, ' #274 FOR_ITER') -+393: jump(p1, p0, p3, p4, p5, p6, p7, p8, p9, p10, p11, p12, i63, p14, i61, p16, p17, i53, p18, p19, p21, p22, p23, p24, p25, p26, p27, descr=TargetToken(2876835874912)) -+405: --end of the loop-- -[d4bd7a0493a] jit-log-opt-bridge} -[d4bd852c8ce] {jit-backend -[d4bd8952728] {jit-backend-dump +SYS_EXECUTABLE python +CODE_DUMP @7fe7c97fbd02 +0 71010000 +[19c475989294] jit-backend-dump} +[19c475989b43] {jit-backend-dump BACKEND x86_64 -SYS_EXECUTABLE pypy -CODE_DUMP @29dd4438198 +0 4881EC9800000048896C24604889FD48895C24684C896424704C896C24784C89B424800000004C89BC248800000049BB30CF61CD99020000498B1B48892B4883C30849891B49BB1867E6CE99020000498B034829E049BBE0E6ACCE99020000493B03760D49BBA77243D49D02000041FFD349BB38411FD29D0200004D8B3B4D8D770149BB38411FD29D0200004D89334C8BB5380100004D8B7E704D8B6E604D8B66784D8B96800000004D8B4E504D0FB6868E000000498B7E58498B7668488B5E10488B5618488B4620488B4E2848899D48010000488B5E3048898550010000488B463848898558010000488B46404C89AD600100004C8B6E484C89AD680100004C8B6E504C898D700100004C8B4E5848899578010000488B566048898D80010000488B4E6848898D88010000488B4E7048898D90010000488B4E784C8995980100004889BDA0010000488985A80100004C89ADB00100004C898DB8010000488995C001000048898DC801000049BB50411FD29D020000498B0B488D510149BB50411FD29D0200004989134983FC080F85000000004C8BA56801000041813C2430EB00000F8500000000498B5424104885D20F8400000000498B4C24084C8B4A1041813990EA03000F85000000004C8B4A08498B51084839D10F8300000000498B51104C8B6CCA10488D510149895424084983F8000F85000000004983FD000F85000000004883FB017206813B582800000F85000000004C8B430848899D380100004C89B5A00100004C898DA80100004C89BDB0010000488995B80100004C89C74C89C649BB888043D49D0200004C895D2049BB7026E0CC9902000041FFD349BB30CF61CD99020000498B0B488B69F8F6450401740D49BB306243D49D02000041FFD348C745200000000049BB40D3E5CE9902000049833B000F8500000000488B95B001000049BBC088C4D09D0200004C39DA0F8500000000488B95A00100004C8B7A0849BBF832C3D09D0200004D39DF0F85000000004D8B4F1049BB1033C3D09D0200004D39D90F8500000000488985380100004889C749BBC0EAC4D09D0200004C89DE49BBE88043D49D0200004C895D2049BBE031E0CC9902000041FFD349BB30CF61CD99020000498B0B488B69F8F6450401740D49BB306243D49D02000041FFD348C7452000000000480FB6C04885C00F850000000049BBC066E6CE99020000498B034883F8000F8C000000004C89ADB001000049BB68411FD29D0200004D8B2B498D450149BB68411FD29D020000498903488B85A80100004C8B68084C39ADB80100000F83000000004C8B6810488B95B80100004D8B7CD5104C8D6A01488B95680100004C896A084983FF000F8500000000488BBD38010000488BB53801000049BB388143D49D0200004C895D2049BB7026E0CC9902000041FFD349BB30CF61CD99020000498B0B488B69F8F6450401740D49BB306243D49D02000041FFD348C745200000000049BB40D3E5CE9902000049833B000F8500000000488985380100004889C749BBC0EAC4D09D0200004C89DE49BB688143D49D0200004C895D2049BBE031E0CC9902000041FFD349BB30CF61CD99020000498B0B488B69F8F6450401740D49BB306243D49D02000041FFD348C7452000000000480FB6C04885C00F850000000049BBC066E6CE99020000498B034883F8000F8C000000004C89BDB00100004C89ADB8010000E9A3FEFFFF49BBE04356D39D020000415349BB088043D49D020000415349BB006043D49D02000041FFE349BB405C56D39D020000415349BB188043D49D020000415349BB006043D49D02000041FFE349BBC85B56D39D020000415349BB288043D49D020000415349BB006043D49D02000041FFE349BB505B56D39D020000415349BB388043D49D020000415349BB006043D49D02000041FFE349BBD85A56D39D020000415349BB488043D49D020000415349BB006043D49D02000041FFE349BB605A56D39D020000415349BB588043D49D020000415349BB006043D49D02000041FFE349BBE85956D39D020000415349BB688043D49D020000415349BB006043D49D02000041FFE349BB705956D39D020000415349BB788043D49D020000415349BB006043D49D02000041FFE349BBF85856D39D020000415349BB988043D49D020000415349BB936043D49D02000041FFE349BB805856D39D020000415349BBA88043D49D020000415349BB006043D49D02000041FFE349BB085856D39D020000415349BBB88043D49D020000415349BB006043D49D02000041FFE349BB905756D39D020000415349BBC88043D49D020000415349BB006043D49D02000041FFE349BB185756D39D020000415349BBD88043D49D020000415349BB006043D49D02000041FFE349BBA05656D39D020000415349BBF88043D49D020000415349BB006043D49D02000041FFE349BB285656D39D020000415349BB088143D49D020000415349BB006043D49D02000041FFE349BBB05556D39D020000415349BB188143D49D020000415349BB006043D49D02000041FFE349BB385556D39D020000415349BB288143D49D020000415349BB006043D49D02000041FFE349BBC05456D39D020000415349BB488143D49D020000415349BB936043D49D02000041FFE349BB485456D39D020000415349BB588143D49D020000415349BB006043D49D02000041FFE349BBD05356D39D020000415349BB788143D49D020000415349BB006043D49D02000041FFE349BB585356D39D020000415349BB888143D49D020000415349BB006043D49D02000041FFE3 -[d4bd899e5b6] jit-backend-dump} -[d4bd899feba] {jit-backend-addr -Loop 1 ( #64 FOR_ITER) has address 0x29dd4438209 to 0x29dd443866b (bootstrap 0x29dd4438198) -[d4bd89a36c2] jit-backend-addr} -[d4bd89a4c38] {jit-backend-dump +SYS_EXECUTABLE python +CODE_DUMP @7fe7c97fbd14 +0 84010000 +[19c47598a8c3] jit-backend-dump} +[19c47598ae17] {jit-backend-dump BACKEND x86_64 -SYS_EXECUTABLE pypy -CODE_DUMP @29dd4438328 +0 3F030000 -[d4bd89a8146] jit-backend-dump} -[d4bd89c766a] {jit-backend-dump +SYS_EXECUTABLE python +CODE_DUMP @7fe7c97fbd1e +0 9F010000 +[19c47598b818] jit-backend-dump} +[19c47598bc6c] {jit-backend-dump BACKEND x86_64 -SYS_EXECUTABLE pypy -CODE_DUMP @29dd443833d +0 4F030000 -[d4bd89cb632] jit-backend-dump} -[d4bd89cc7b2] {jit-backend-dump +SYS_EXECUTABLE python +CODE_DUMP @7fe7c97fbd31 +0 B1010000 +[19c47598c665] jit-backend-dump} +[19c47598cacb] {jit-backend-dump BACKEND x86_64 -SYS_EXECUTABLE pypy -CODE_DUMP @29dd443834b +0 66030000 -[d4bd89cf62e] jit-backend-dump} -[d4bd89d04ac] {jit-backend-dump +SYS_EXECUTABLE python +CODE_DUMP @7fe7c97fbd42 +0 C5010000 +[19c47598d49a] jit-backend-dump} +[19c47598d8fa] {jit-backend-dump BACKEND x86_64 -SYS_EXECUTABLE pypy -CODE_DUMP @29dd4438361 +0 75030000 -[d4bd89d2d4c] jit-backend-dump} -[d4bd89d3bda] {jit-backend-dump +SYS_EXECUTABLE python +CODE_DUMP @7fe7c97fbd55 +0 D7010000 +[19c47598e2a2] jit-backend-dump} +[19c47598e6f7] {jit-backend-dump BACKEND x86_64 -SYS_EXECUTABLE pypy -CODE_DUMP @29dd4438372 +0 89030000 -[d4bd89d622c] jit-backend-dump} -[d4bd89d725c] {jit-backend-dump +SYS_EXECUTABLE python +CODE_DUMP @7fe7c97fbd8d +0 C4010000 +[19c47598f0d7] jit-backend-dump} +[19c47598f58b] {jit-backend-dump BACKEND x86_64 -SYS_EXECUTABLE pypy -CODE_DUMP @29dd443838e +0 92030000 -[d4bd89d9b86] jit-backend-dump} -[d4bd89dadfa] {jit-backend-dump +SYS_EXECUTABLE python +CODE_DUMP @7fe7c97fbd9f +0 D7010000 +[19c47598ff0c] jit-backend-dump} +[19c475990358] {jit-backend-dump BACKEND x86_64 -SYS_EXECUTABLE pypy -CODE_DUMP @29dd4438398 +0 AD030000 -[d4bd89dd794] jit-backend-dump} -[d4bd89de63e] {jit-backend-dump +SYS_EXECUTABLE python +CODE_DUMP @7fe7c97fbdad +0 EE010000 +[19c475990cbc] jit-backend-dump} +[19c475991353] {jit-backend-dump BACKEND x86_64 -SYS_EXECUTABLE pypy -CODE_DUMP @29dd44383aa +0 C0030000 -[d4bd89e1648] jit-backend-dump} -[d4bd89e26b2] {jit-backend-dump +SYS_EXECUTABLE python +CODE_DUMP @7fe7c97fbdca +0 1B020000 +[19c475991cea] jit-backend-dump} +[19c47599220b] {jit-backend-dump BACKEND x86_64 -SYS_EXECUTABLE pypy -CODE_DUMP @29dd4438432 +0 5D030000 -[d4bd89e4e34] jit-backend-dump} -[d4bd89e5ccc] {jit-backend-dump +SYS_EXECUTABLE python +CODE_DUMP @7fe7c97fbdf6 +0 14020000 +[19c475992b2e] jit-backend-dump} +[19c47599305b] {jit-backend-dump BACKEND x86_64 -SYS_EXECUTABLE pypy -CODE_DUMP @29dd443844c +0 68030000 -[d4bd89e836c] jit-backend-dump} -[d4bd89e91b6] {jit-backend-dump +SYS_EXECUTABLE python +CODE_DUMP @7fe7c97fbe09 +0 26020000 +[19c475993ac7] jit-backend-dump} +[19c475993f4b] {jit-backend-dump BACKEND x86_64 -SYS_EXECUTABLE pypy -CODE_DUMP @29dd443846a +0 6F030000 -[d4bd89eb7ba] jit-backend-dump} -[d4bd89ec5c8] {jit-backend-dump +SYS_EXECUTABLE python +CODE_DUMP @7fe7c97fbe40 +0 14020000 +[19c47599496a] jit-backend-dump} +[19c475994dad] {jit-backend-dump BACKEND x86_64 -SYS_EXECUTABLE pypy -CODE_DUMP @29dd4438481 +0 7D030000 -[d4bd89eeb16] jit-backend-dump} -[d4bd89f0224] {jit-backend-dump +SYS_EXECUTABLE python +CODE_DUMP @7fe7c97fbe51 +0 28020000 +[19c4759956f9] jit-backend-dump} +[19c475995c29] {jit-backend-dump BACKEND x86_64 -SYS_EXECUTABLE pypy -CODE_DUMP @29dd44384ec +0 5C030000 -[d4bd89f27c0] jit-backend-dump} -[d4bd89f375c] {jit-backend-dump +SYS_EXECUTABLE python +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=) ++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(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] +debug_merge_point(0, 0, ' #18 LOAD_CONST') ++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] +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] ++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] +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] +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] +debug_merge_point(0, 0, ' #60 STORE_FAST') +debug_merge_point(0, 0, ' #63 LOAD_FAST') +debug_merge_point(0, 0, ' #66 LOAD_CONST') +debug_merge_point(0, 0, ' #69 INPLACE_ADD') ++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: i43 = getfield_raw(51804288, descr=) ++444: i45 = int_lt(i43, 0) +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(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] +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] ++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] +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] +debug_merge_point(0, 0, ' #60 STORE_FAST') +debug_merge_point(0, 0, ' #63 LOAD_FAST') +debug_merge_point(0, 0, ' #66 LOAD_CONST') +debug_merge_point(0, 0, ' #69 INPLACE_ADD') ++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: 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] +debug_merge_point(0, 0, ' #15 LOAD_FAST') ++618: jump(p0, p1, p2, p3, p6, i53, i54, descr=TargetToken(140633495990168)) ++623: --end of the loop-- +[19c4759ebff6] jit-log-opt-loop} +[19c475ad90fd] {jit-backend +[19c475b60e23] {jit-backend-dump BACKEND x86_64 -SYS_EXECUTABLE pypy -CODE_DUMP @29dd4438503 +0 6A030000 -[d4bd89f5e88] jit-backend-dump} -[d4bd89f6e3c] {jit-backend-dump +SYS_EXECUTABLE python +CODE_DUMP @7fe7c97fc130 +0 48817D50FFFFFF007D2448C7442408FFFFFF0049BBF0C07FC9E77F00004C891C2449BB75A27FC9E77F000041FFD349BBF8E167CCE77F00004D8B0B498D510149BBF8E167CCE77F0000498913488B95580100004C8B4A10488B4A1848C74010000000004883F9020F85000000004D85C90F85000000004C8B8D38010000498B4968488B0425484CB601488D7820483B3C25684CB601761B49BB20C17FC9E77F00004C891C2449BBE3A97FC9E77F000041FFD348893C25484CB60148C700180C000041C6818D00000001488BBD5001000041F6410401740F415149BB2EA17FC9E77F000041FFD34989B980000000488BBD4801000041F6410401740F415149BB2EA17FC9E77F000041FFD34989795041F6410401740F415149BB2EA17FC9E77F000041FFD349BB38CF0CCAE77F00004D89597041C6818E0000000049C741600000000049C741780200000049C741582A000000F6410481741678105149BB91A17FC9E77F000041FFD379048049FF01488941104C8D481049C701180C0000488BBD6001000049897908F6410481741678105149BB91A17FC9E77F000041FFD379048049FF014C89491848C741200000000048C741280000000048C74130000000004C8960084889455848C745108042EA0149BB301068CCE77F00004C895D204889E84C8BBC24880000004C8BB424800000004C8B6C24784C8B642470488B5C2468488B6C24604881C498000000C349BB40FC96C9E77F0000415349BB00C17FC9E77F0000415349BB00A07FC9E77F000041FFE349BB986054CCE77F0000415349BB10C17FC9E77F0000415349BB00A07FC9E77F000041FFE3 +[19c475b67831] jit-backend-dump} +[19c475b68364] {jit-backend-dump BACKEND x86_64 -SYS_EXECUTABLE pypy -CODE_DUMP @29dd4438540 +0 52030000 -[d4bd89f9804] jit-backend-dump} -[d4bd89fa622] {jit-backend-dump +SYS_EXECUTABLE python +CODE_DUMP @7fe7c97fc134 +0 22000000 +[19c475b68e8f] jit-backend-dump} +[19c475b693cb] {jit-backend-dump BACKEND x86_64 -SYS_EXECUTABLE pypy -CODE_DUMP @29dd4438569 +0 4E030000 -[d4bd89fce48] jit-backend-dump} -[d4bd89fdc78] {jit-backend-dump +SYS_EXECUTABLE python +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 pypy -CODE_DUMP @29dd44385d2 +0 0A030000 -[d4bd8a00248] jit-backend-dump} -[d4bd8a01288] {jit-backend-dump +SYS_EXECUTABLE python +CODE_DUMP @7fe7c97fc199 +0 A0010000 +[19c475b6c292] jit-backend-dump} +[19c475b6c766] {jit-backend-dump BACKEND x86_64 -SYS_EXECUTABLE pypy -CODE_DUMP @29dd443863d +0 E9020000 -[d4bd8a03b30] jit-backend-dump} -[d4bd8a04982] {jit-backend-dump +SYS_EXECUTABLE python +CODE_DUMP @7fe7c97fc1a2 +0 BC010000 +[19c475b6d09d] jit-backend-dump} +[19c475b6d7ac] {jit-backend-dump BACKEND x86_64 -SYS_EXECUTABLE pypy -CODE_DUMP @29dd4438654 +0 F7020000 -[d4bd8a070a6] jit-backend-dump} -[d4bd8a0933e] jit-backend} -[d4bd8a0ddf6] {jit-log-opt-loop -# Loop 1 ( #64 FOR_ITER) : loop with 105 ops +SYS_EXECUTABLE python +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] +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] ++118: p15 = getfield_gc(p1, descr=) ++129: p16 = getfield_gc(p1, descr=) +p18 = new_with_vtable(ConstClass(W_IntObject)) ++193: setfield_gc(p1, 1, descr=) +setfield_gc(p1, p6, descr=) +setfield_gc(p1, p7, descr=) +setfield_gc(p1, ConstPtr(ptr20), descr=) ++306: setfield_gc(p1, 0, descr=) ++314: setfield_gc(p1, ConstPtr(ptr22), descr=) ++322: setfield_gc(p1, 2, descr=) ++330: setfield_gc(p1, 42, descr=) +setarrayitem_gc(p15, 0, p18, descr=) +p27 = new_with_vtable(ConstClass(W_IntObject)) ++381: setfield_gc(p27, i9, descr=) +setarrayitem_gc(p15, 1, p27, descr=) ++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-- +[19c475b92846] jit-log-opt-bridge} +[19c47608ae49] {jit-backend +[19c47620d562] {jit-backend-dump +BACKEND x86_64 +SYS_EXECUTABLE python +CODE_DUMP @7fe7c97fc568 +0 48817D50FFFFFF007D2448C7442408FFFFFF0049BB88C37FC9E77F00004C891C2449BB75A27FC9E77F000041FFD349BB10E267CCE77F0000498B034C8D780149BB10E267CCE77F00004D893B4C8BBD38010000498B470849BBB00007CAE77F00004C39D80F85000000004C8B701049BB900E0CCAE77F00004D39DE0F850000000049BBC8C37FC9E77F00004C895D2041BBA05B840041FFD3F6450401740D49BBFDA17FC9E77F000041FFD348C74520000000004C8B78504989EE4C8B68604D85ED0F85000000004C8B68404983FD000F85000000004C8B2C2500EFCE014981FDF0EED4010F85000000004C8B2C25807816034983FD000F8C000000004989ED48898570010000488B0425484CB601488DB840010000483B3C25684CB601761B49BB28C47FC9E77F00004C891C2449BBE3A97FC9E77F000041FFD348893C25484CB60148C700407E0100488DB89000000048C707C800000048C74708050000004C8D673849C70424180C00004D8D54241049C702180C00004D8D4A1049C701E82200004D8D411849C70070400000498D701848C706C800000048C7460800000000488D5E1048C703180600004C8973084C8BB57001000041F6460401740F415649BB2EA17FC9E77F000041FFD349895E50488B9538010000F6420401740E5249BB2EA17FC9E77F000041FFD34C896A1849C7442408010000004C8967104C89571849BB808554CCE77F00004D89580849C74010C01CF1014D89411049C74108010000004C894F204889786848C740780300000049BBA08554CCE77F00004C8958604C89783048C740581300000048897028C780880000001500000049BBB00007CAE77F00004C89580849BB38CF0CCAE77F00004C89587049BB60B57FC9E77F0000498B3348898578010000488B3C25484CB6014889F84801F7483B3C25684CB601761B49BB38C47FC9E77F00004C891C2449BBE3A97FC9E77F000041FFD348893C25484CB60148C7000800000049BB58B57FC9E77F0000498B334889705049BB58B57FC9E77F00004C895808488BB5780100004889B0380100004C89B04001000048899D8001000049BB204C56CCE77F00004C895D184889C749BB58C47FC9E77F00004C895D2049BB68B67FC9E77F000041FFD3F6450401740D49BBFDA17FC9E77F000041FFD348C7452000000000488178108042EA01743E4889C7488BB57801000049BB68C47FC9E77F00004C895D2041BB908D080141FFD3F6450401740D49BBFDA17FC9E77F000041FFD348C7452000000000EB13488B957801000048C7421800000000488B405848837D10000F850000000048833C2500E61503000F8500000000488B9570010000488B5A604885DB0F8500000000488B5A40488BB57801000048C74650000000004883FB000F8500000000488B5A504C8B7630480FB6BE8C000000F6420401740E5249BB2EA17FC9E77F000041FFD34C8972504885FF0F8500000000488BBD8001000048C74708000000008138180C00000F8500000000488B7808488B95600100004801FA0F8000000000488BBD680100004883C7010F8000000000488B0425807816034883F8000F8C0000000049BB28E267CCE77F0000498B03488D700149BB28E267CCE77F00004989334881FF102700000F8D0000000049BB00000000000000804C39DF0F84000000004889F8B9020000004889956001000048898568010000489948F7F94889D048C1FA3FBF020000004821D74801F84883F8000F8500000000488B85600100004883C0010F8000000000488BBD680100004883C701488B1425807816034883FA000F8C000000004889FB49BBCEBD7FC9E77F000041FFE349BB786254CCE77F0000415349BB98C37FC9E77F0000415349BB00A07FC9E77F000041FFE349BB587356CCE77F0000415349BBA8C37FC9E77F0000415349BB00A07FC9E77F000041FFE349BBE07256CCE77F0000415349BBB8C37FC9E77F0000415349BB00A07FC9E77F000041FFE349BB687256CCE77F0000415349BBD8C37FC9E77F0000415349BB00A07FC9E77F000041FFE349BBF07156CCE77F0000415349BBE8C37FC9E77F0000415349BB00A07FC9E77F000041FFE349BB787156CCE77F0000415349BBF8C37FC9E77F0000415349BB00A07FC9E77F000041FFE349BB007156CCE77F0000415349BB08C47FC9E77F0000415349BB00A07FC9E77F000041FFE349BB887056CCE77F0000415349BB18C47FC9E77F0000415349BB00A07FC9E77F000041FFE349BB204C56CCE77F0000415349BB48C47FC9E77F0000415349BB85A07FC9E77F000041FFE349BB107056CCE77F0000415349BB78C47FC9E77F0000415349BB85A07FC9E77F000041FFE349BB986F56CCE77F0000415349BB88C47FC9E77F0000415349BB00A07FC9E77F000041FFE349BB206F56CCE77F0000415349BB98C47FC9E77F0000415349BB00A07FC9E77F000041FFE349BBA86E56CCE77F0000415349BBA8C47FC9E77F0000415349BB00A07FC9E77F000041FFE349BB306E56CCE77F0000415349BBB8C47FC9E77F0000415349BB00A07FC9E77F000041FFE349BBB86D56CCE77F0000415349BBC8C47FC9E77F0000415349BB00A07FC9E77F000041FFE349BB406D56CCE77F0000415349BBD8C47FC9E77F0000415349BB00A07FC9E77F000041FFE349BBC86C56CCE77F0000415349BBE8C47FC9E77F0000415349BB00A07FC9E77F000041FFE349BB506C56CCE77F0000415349BBF8C47FC9E77F0000415349BB00A07FC9E77F000041FFE349BBD86B56CCE77F0000415349BB08C57FC9E77F0000415349BB00A07FC9E77F000041FFE349BB606B56CCE77F0000415349BB18C57FC9E77F0000415349BB00A07FC9E77F000041FFE349BBE86A56CCE77F0000415349BB28C57FC9E77F0000415349BB00A07FC9E77F000041FFE349BB706A56CCE77F0000415349BB38C57FC9E77F0000415349BB00A07FC9E77F000041FFE349BBF86956CCE77F0000415349BB48C57FC9E77F0000415349BB00A07FC9E77F000041FFE349BB806956CCE77F0000415349BB58C57FC9E77F0000415349BB00A07FC9E77F000041FFE3 +[19c4762283c4] jit-backend-dump} +[19c476229554] {jit-backend-dump +BACKEND x86_64 +SYS_EXECUTABLE python +CODE_DUMP @7fe7c97fc56c +0 26000000 +[19c47622a4ac] jit-backend-dump} +[19c47622a9be] {jit-backend-dump +BACKEND x86_64 +SYS_EXECUTABLE python +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 @7fe7c97fc5ce +0 C0040000 +[19c47622d7fc] jit-backend-dump} +[19c47622ddfa] {jit-backend-dump +BACKEND x86_64 +SYS_EXECUTABLE python +CODE_DUMP @7fe7c97fc5e5 +0 CE040000 +[19c47622e73d] jit-backend-dump} +[19c47622ed4f] {jit-backend-dump +BACKEND x86_64 +SYS_EXECUTABLE python +CODE_DUMP @7fe7c97fc62b +0 D2040000 +[19c47622f6b6] jit-backend-dump} +[19c47622faf5] {jit-backend-dump +BACKEND x86_64 +SYS_EXECUTABLE python +CODE_DUMP @7fe7c97fc639 +0 E9040000 +[19c4762303fd] jit-backend-dump} +[19c476230872] {jit-backend-dump +BACKEND x86_64 +SYS_EXECUTABLE python +CODE_DUMP @7fe7c97fc64e +0 1E050000 +[19c476231192] jit-backend-dump} +[19c4762315d1] {jit-backend-dump +BACKEND x86_64 +SYS_EXECUTABLE python +CODE_DUMP @7fe7c97fc660 +0 31050000 +[19c476231eb5] jit-backend-dump} +[19c4762322c8] {jit-backend-dump +BACKEND x86_64 +SYS_EXECUTABLE python +CODE_DUMP @7fe7c97fc918 +0 9E020000 +[19c476232b8c] jit-backend-dump} +[19c476232fec] {jit-backend-dump +BACKEND x86_64 +SYS_EXECUTABLE python +CODE_DUMP @7fe7c97fc927 +0 B4020000 +[19c476233926] jit-backend-dump} +[19c476233d6c] {jit-backend-dump +BACKEND x86_64 +SYS_EXECUTABLE python +CODE_DUMP @7fe7c97fc93b +0 C5020000 +[19c476236834] jit-backend-dump} +[19c476236d7c] {jit-backend-dump +BACKEND x86_64 +SYS_EXECUTABLE python +CODE_DUMP @7fe7c97fc958 +0 CD020000 +[19c47623773c] jit-backend-dump} +[19c476237b4c] {jit-backend-dump +BACKEND x86_64 +SYS_EXECUTABLE python +CODE_DUMP @7fe7c97fc989 +0 C1020000 +[19c476238442] jit-backend-dump} +[19c476238835] {jit-backend-dump +BACKEND x86_64 +SYS_EXECUTABLE python +CODE_DUMP @7fe7c97fc9a4 +0 CB020000 +[19c476239131] jit-backend-dump} +[19c476239535] {jit-backend-dump +BACKEND x86_64 +SYS_EXECUTABLE python +CODE_DUMP @7fe7c97fc9b8 +0 DC020000 +[19c476239e16] jit-backend-dump} +[19c47623a220] {jit-backend-dump +BACKEND x86_64 +SYS_EXECUTABLE python +CODE_DUMP @7fe7c97fc9c9 +0 F0020000 +[19c47623aae9] jit-backend-dump} +[19c47623b4a3] {jit-backend-dump +BACKEND x86_64 +SYS_EXECUTABLE python +CODE_DUMP @7fe7c97fc9db +0 28030000 +[19c47623bddb] jit-backend-dump} +[19c47623c1eb] {jit-backend-dump +BACKEND x86_64 +SYS_EXECUTABLE python +CODE_DUMP @7fe7c97fca06 +0 22030000 +[19c47623ca8a] jit-backend-dump} +[19c47623ce89] {jit-backend-dump +BACKEND x86_64 +SYS_EXECUTABLE python +CODE_DUMP @7fe7c97fca19 +0 34030000 +[19c47623d73a] jit-backend-dump} +[19c47623db4a] {jit-backend-dump +BACKEND x86_64 +SYS_EXECUTABLE python +CODE_DUMP @7fe7c97fca50 +0 22030000 +[19c47623e458] jit-backend-dump} +[19c47623e859] {jit-backend-dump +BACKEND x86_64 +SYS_EXECUTABLE python +CODE_DUMP @7fe7c97fca61 +0 36030000 +[19c47623f149] jit-backend-dump} +[19c47623f5ac] {jit-backend-dump +BACKEND x86_64 +SYS_EXECUTABLE python +CODE_DUMP @7fe7c97fca7e +0 63030000 +[19c47623fe90] jit-backend-dump} +[19c4762406c8] {jit-backend-dump +BACKEND x86_64 +SYS_EXECUTABLE python +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] ++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] +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] ++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] +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: p20 = getfield_gc(ConstPtr(ptr19), descr=) ++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') +debug_merge_point(1, 1, ' #19 FOR_ITER') +debug_merge_point(1, 1, ' #22 STORE_FAST') +debug_merge_point(1, 1, ' #25 LOAD_FAST') +debug_merge_point(1, 1, ' #28 LOAD_CONST') +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(51804288, descr=) ++242: i25 = int_lt(i23, 0) +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) +p30 = new_array(5, descr=) +p32 = new_with_vtable(ConstClass(W_IntObject)) +p34 = new_with_vtable(ConstClass(W_IntObject)) +p36 = new_with_vtable(26177128) +p38 = new_with_vtable(ConstClass(W_ListObject)) +p40 = new_array(0, descr=) +p42 = new_with_vtable(26169752) ++427: setfield_gc(p42, p15, descr=) +setfield_gc(p13, p42, descr=) +setfield_gc(p1, p26, 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, i6, i7] ++948: keepalive(p28) ++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] ++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] ++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] +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] ++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] +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] +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(51804288, descr=) ++1133: i73 = int_lt(i71, 0) +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(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] +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] ++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] +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] +debug_merge_point(0, 0, ' #60 STORE_FAST') +debug_merge_point(0, 0, ' #63 LOAD_FAST') +debug_merge_point(0, 0, ' #66 LOAD_CONST') +debug_merge_point(0, 0, ' #69 INPLACE_ADD') ++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(51804288, descr=) ++1296: i92 = int_lt(i90, 0) +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(140633495990168)) ++1322: --end of the loop-- +[19c4762c0a61] jit-log-opt-bridge} +[19c476497d1a] {jit-backend-dump +BACKEND x86_64 +SYS_EXECUTABLE python +CODE_DUMP @7fe7c97fbdbc +0 E903020000 +[19c47649be73] jit-backend-dump} +[19c47649c3b8] {jit-backend-dump +BACKEND x86_64 +SYS_EXECUTABLE python +CODE_DUMP @7fe7c97fbe60 +0 E93D020000 +[19c47649ce6f] jit-backend-dump} +[19c47649d42e] {jit-backend-dump +BACKEND x86_64 +SYS_EXECUTABLE python +CODE_DUMP @7fe7c97fc5e9 +0 E9EE040000 +[19c47649e0fb] jit-backend-dump} +[19c47649e5b2] {jit-backend-dump +BACKEND x86_64 +SYS_EXECUTABLE python +CODE_DUMP @7fe7c97fc63d +0 E909050000 +[19c47649efa7] jit-backend-dump} +[19c47649f437] {jit-backend-dump +BACKEND x86_64 +SYS_EXECUTABLE python +CODE_DUMP @7fe7c97fc9cd +0 E910030000 +[19c47649fddf] jit-backend-dump} +[19c4764a029c] {jit-backend-dump +BACKEND x86_64 +SYS_EXECUTABLE python +CODE_DUMP @7fe7c97fca70 +0 E94B030000 +[19c4764a0c44] jit-backend-dump} +[19c476926513] {jit-backend +[19c4769db8ef] {jit-backend-dump +BACKEND x86_64 +SYS_EXECUTABLE python +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 @7fe7c97fd0e4 +0 61030000 +[19c4769fb2d8] jit-backend-dump} +[19c4769fb916] {jit-backend-dump +BACKEND x86_64 +SYS_EXECUTABLE python +CODE_DUMP @7fe7c97fd0f8 +0 72030000 +[19c4769fc368] jit-backend-dump} +[19c4769fc7d1] {jit-backend-dump +BACKEND x86_64 +SYS_EXECUTABLE python +CODE_DUMP @7fe7c97fd105 +0 8A030000 +[19c4769fd141] jit-backend-dump} +[19c4769fd58f] {jit-backend-dump +BACKEND x86_64 +SYS_EXECUTABLE python +CODE_DUMP @7fe7c97fd119 +0 9B030000 +[19c4769fdf05] jit-backend-dump} +[19c4769fe36b] {jit-backend-dump +BACKEND x86_64 +SYS_EXECUTABLE python +CODE_DUMP @7fe7c97fd133 +0 A6030000 +[19c4769fec55] jit-backend-dump} +[19c4769ff071] {jit-backend-dump +BACKEND x86_64 +SYS_EXECUTABLE python +CODE_DUMP @7fe7c97fd13c +0 C2030000 +[19c4769ff94f] jit-backend-dump} +[19c4769ffd80] {jit-backend-dump +BACKEND x86_64 +SYS_EXECUTABLE python +CODE_DUMP @7fe7c97fd15b +0 C8030000 +[19c476a006ea] jit-backend-dump} +[19c476a00b26] {jit-backend-dump +BACKEND x86_64 +SYS_EXECUTABLE python +CODE_DUMP @7fe7c97fd16e +0 DA030000 +[19c476a01413] jit-backend-dump} +[19c476a0183b] {jit-backend-dump +BACKEND x86_64 +SYS_EXECUTABLE python +CODE_DUMP @7fe7c97fd185 +0 E8030000 +[19c476a0210a] jit-backend-dump} +[19c476a02535] {jit-backend-dump +BACKEND x86_64 +SYS_EXECUTABLE python +CODE_DUMP @7fe7c97fd19d +0 F5030000 +[19c476a02dba] jit-backend-dump} +[19c476a0345e] {jit-backend-dump +BACKEND x86_64 +SYS_EXECUTABLE python +CODE_DUMP @7fe7c97fd1b2 +0 2A040000 +[19c476a03d83] jit-backend-dump} +[19c476a041c6] {jit-backend-dump +BACKEND x86_64 +SYS_EXECUTABLE python +CODE_DUMP @7fe7c97fd212 +0 EF030000 +[19c476a04af7] jit-backend-dump} +[19c476a04fe6] {jit-backend-dump +BACKEND x86_64 +SYS_EXECUTABLE python +CODE_DUMP @7fe7c97fd22a +0 FC030000 +[19c476a058d0] jit-backend-dump} +[19c476a05cf8] {jit-backend-dump +BACKEND x86_64 +SYS_EXECUTABLE python +CODE_DUMP @7fe7c97fd292 +0 B9030000 +[19c476a06592] jit-backend-dump} +[19c476a069d4] {jit-backend-dump +BACKEND x86_64 +SYS_EXECUTABLE python +CODE_DUMP @7fe7c97fd2eb +0 85030000 +[19c476a096d4] jit-backend-dump} +[19c476a09f21] {jit-backend-dump +BACKEND x86_64 +SYS_EXECUTABLE python +CODE_DUMP @7fe7c97fd312 +0 83030000 +[19c476a0a999] jit-backend-dump} +[19c476a0aeb2] {jit-backend-dump +BACKEND x86_64 +SYS_EXECUTABLE python +CODE_DUMP @7fe7c97fd381 +0 5E030000 +[19c476a0b824] jit-backend-dump} +[19c476a0bc29] {jit-backend-dump +BACKEND x86_64 +SYS_EXECUTABLE python +CODE_DUMP @7fe7c97fd3e2 +0 22030000 +[19c476a0c4e6] jit-backend-dump} +[19c476a0c908] {jit-backend-dump +BACKEND x86_64 +SYS_EXECUTABLE python +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] -+143: p2 = getfield_gc(p0, descr=) -+154: p3 = getfield_gc(p0, descr=) -+158: i4 = getfield_gc(p0, descr=) -+162: p5 = getfield_gc(p0, descr=) -+169: p6 = getfield_gc(p0, descr=) -+173: i7 = getfield_gc(p0, descr=) -+181: i8 = getfield_gc(p0, descr=) -+185: p9 = getfield_gc(p0, descr=) -+189: p11 = getarrayitem_gc(p9, 0, descr=) -+193: p13 = getarrayitem_gc(p9, 1, descr=) -+197: p15 = getarrayitem_gc(p9, 2, descr=) -+201: p17 = getarrayitem_gc(p9, 3, descr=) -+205: p19 = getarrayitem_gc(p9, 4, descr=) -+216: p21 = getarrayitem_gc(p9, 5, descr=) -+227: p23 = getarrayitem_gc(p9, 6, descr=) -+238: p25 = getarrayitem_gc(p9, 7, descr=) -+249: p27 = getarrayitem_gc(p9, 8, descr=) -+260: p29 = getarrayitem_gc(p9, 9, descr=) -+271: p31 = getarrayitem_gc(p9, 10, descr=) -+282: p33 = getarrayitem_gc(p9, 11, descr=) -+293: p35 = getarrayitem_gc(p9, 12, descr=) -+304: p37 = getarrayitem_gc(p9, 13, descr=) -+315: p38 = getfield_gc(p0, descr=) -+315: label(p0, p1, p2, p3, i4, p5, p6, i7, i8, p11, p13, p15, p17, p19, p21, p23, p25, p27, p29, p31, p33, p35, p37, descr=TargetToken(2876835876584)) -debug_merge_point(0, 0, ' #64 FOR_ITER') -+394: guard_value(i4, 8, descr=) [i4, p1, p0, p2, p3, p5, p6, i7, i8, p11, p13, p15, p17, p19, p21, p23, p25, p27, p29, p31, p33, p35, p37] -+404: guard_class(p25, 2859595984528, descr=) [p1, p0, p25, p2, p3, p5, p6, i7, p11, p13, p15, p17, p19, p21, p23, p27, p29, p31, p33, p35, p37] -+425: p41 = getfield_gc(p25, descr=) -+430: guard_nonnull(p41, descr=) [p1, p0, p25, p41, p2, p3, p5, p6, i7, p11, p13, p15, p17, p19, p21, p23, p27, p29, p31, p33, p35, p37] -+439: i42 = getfield_gc(p25, descr=) -+444: p43 = getfield_gc(p41, descr=) -+448: guard_class(p43, 2859596180976, descr=) [p1, p0, p25, i42, p43, p41, p2, p3, p5, p6, i7, p11, p13, p15, p17, p19, p21, p23, p27, p29, p31, p33, p35, p37] -+461: p45 = getfield_gc(p41, descr=) -+465: i46 = getfield_gc(p45, descr=) -+469: i47 = uint_ge(i42, i46) -guard_false(i47, descr=) [p1, p0, p25, i42, i46, p45, p2, p3, p5, p6, i7, p11, p13, p15, p17, p19, p21, p23, p27, p29, p31, p33, p35, p37] -+478: p48 = getfield_gc(p45, descr=) -+482: i49 = getarrayitem_gc(p48, i42, descr=) -+487: i51 = int_add(i42, 1) -+491: setfield_gc(p25, i51, descr=) -+496: guard_value(i7, 0, descr=) [i7, p1, p0, p2, p3, p5, p6, p11, p13, p15, p17, p19, p21, p23, p25, p29, p31, p33, p35, p37, i49] -debug_merge_point(0, 0, ' #67 STORE_FAST') -debug_merge_point(0, 0, ' #70 LOAD_FAST') -debug_merge_point(0, 0, ' #73 POP_JUMP_IF_FALSE') -+506: i53 = int_is_true(i49) -guard_false(i53, descr=) [p1, p0, p2, p3, p5, p6, p11, p13, p15, p17, p19, p21, p25, p29, p31, p33, p35, p37, i49] -debug_merge_point(0, 0, ' #89 LOAD_FAST') -+516: guard_nonnull_class(p19, ConstClass(W_LongObject), descr=) [p1, p0, p19, p2, p3, p5, p6, p11, p13, p15, p17, p21, p25, p29, p31, p33, p35, p37, i49] -debug_merge_point(0, 0, ' #92 LOAD_FAST') -debug_merge_point(0, 0, ' #95 BINARY_ADD') -+534: p55 = getfield_gc_pure(p19, descr=) -+538: p57 = call(ConstClass(rbigint.add), p55, p55, descr=) -+650: guard_no_exception(descr=) [p1, p0, p19, p57, p2, p3, p5, p6, p11, p13, p15, p17, p21, p25, p31, p33, p35, p37, i49] -debug_merge_point(0, 0, ' #96 STORE_FAST') -debug_merge_point(0, 0, ' #99 LOAD_FAST') -debug_merge_point(0, 0, ' #102 LOAD_GLOBAL') -+670: guard_value(p2, ConstPtr(ptr58), descr=) [p1, p0, p2, p3, p5, p6, p11, p13, p15, p17, p21, p25, p31, p33, p35, p37, p57, i49] -+696: p59 = getfield_gc(p0, descr=) -+707: guard_value(p59, ConstPtr(ptr60), descr=) [p1, p0, p59, p3, p5, p6, p11, p13, p15, p17, p21, p25, p31, p33, p35, p37, p57, i49] -+726: p61 = getfield_gc(p59, descr=) -+730: guard_value(p61, ConstPtr(ptr62), descr=) [p1, p0, p61, p59, p3, p5, p6, p11, p13, p15, p17, p21, p25, p31, p33, p35, p37, p57, i49] -+749: guard_not_invalidated(descr=) [p1, p0, p59, p3, p5, p6, p11, p13, p15, p17, p21, p25, p31, p33, p35, p37, p57, i49] -debug_merge_point(0, 0, ' #105 COMPARE_OP') -+749: i65 = call(ConstClass(rbigint.gt), p57, ConstPtr(ptr64), descr=) -+847: guard_false(i65, descr=) [p1, p0, p3, p5, p6, p11, p13, p15, p17, p21, p25, p31, p33, p35, p37, p57, i49] -debug_merge_point(0, 0, ' #108 POP_JUMP_IF_FALSE') -debug_merge_point(0, 0, ' #136 JUMP_ABSOLUTE') -+856: i67 = getfield_raw(2859624457920, descr=) -+869: i69 = int_lt(i67, 0) -guard_false(i69, descr=) [p1, p0, p3, p5, p6, p11, p13, p15, p17, p21, p25, p31, p33, p35, p37, p57, i49] -debug_merge_point(0, 0, ' #64 FOR_ITER') -+879: p70 = same_as(ConstPtr(ptr62)) -+879: label(p0, p1, p3, p5, p6, p11, p13, p15, p17, p57, p21, i49, p25, p31, p33, p35, p37, p45, i51, descr=TargetToken(2876835876672)) -debug_merge_point(0, 0, ' #64 FOR_ITER') -+916: i71 = getfield_gc(p45, descr=) -+927: i72 = uint_ge(i51, i71) -guard_false(i72, descr=) [p1, p0, p25, i51, i71, p45, p3, p5, p6, p11, p13, p15, p17, p21, p31, p33, p35, p37, p57, i49] -+940: p73 = getfield_gc(p45, descr=) -+944: i74 = getarrayitem_gc(p73, i51, descr=) -+956: i75 = int_add(i51, 1) -debug_merge_point(0, 0, ' #67 STORE_FAST') -debug_merge_point(0, 0, ' #70 LOAD_FAST') -debug_merge_point(0, 0, ' #73 POP_JUMP_IF_FALSE') -+960: setfield_gc(p25, i75, descr=) -+971: i76 = int_is_true(i74) -guard_false(i76, descr=) [p1, p0, p3, p5, p6, p11, p13, p15, p17, p21, p25, p31, p33, p35, p37, i74, p57, None] -debug_merge_point(0, 0, ' #89 LOAD_FAST') -debug_merge_point(0, 0, ' #92 LOAD_FAST') -debug_merge_point(0, 0, ' #95 BINARY_ADD') -+981: p78 = call(ConstClass(rbigint.add), p57, p57, descr=) -+1066: guard_no_exception(descr=) [p1, p0, p78, p3, p5, p6, p11, p13, p15, p17, p21, p25, p31, p33, p35, p37, i74, p57, None] -debug_merge_point(0, 0, ' #96 STORE_FAST') -debug_merge_point(0, 0, ' #99 LOAD_FAST') -debug_merge_point(0, 0, ' #102 LOAD_GLOBAL') -+1086: guard_not_invalidated(descr=) [p1, p0, p3, p5, p6, p11, p13, p15, p17, p21, p25, p31, p33, p35, p37, p78, i74, None, None] -debug_merge_point(0, 0, ' #105 COMPARE_OP') -+1086: i79 = call(ConstClass(rbigint.gt), p78, ConstPtr(ptr64), descr=) -+1184: guard_false(i79, descr=) [p1, p0, p3, p5, p6, p11, p13, p15, p17, p21, p25, p31, p33, p35, p37, p78, i74, None, None] -debug_merge_point(0, 0, ' #108 POP_JUMP_IF_FALSE') -debug_merge_point(0, 0, ' #136 JUMP_ABSOLUTE') -+1193: i80 = getfield_raw(2859624457920, descr=) -+1206: i81 = int_lt(i80, 0) -guard_false(i81, descr=) [p1, p0, p3, p5, p6, p11, p13, p15, p17, p21, p25, p31, p33, p35, p37, p78, i74, None, None] -debug_merge_point(0, 0, ' #64 FOR_ITER') -+1216: jump(p0, p1, p3, p5, p6, p11, p13, p15, p17, p78, p21, i74, p25, p31, p33, p35, p37, p45, i75, descr=TargetToken(2876835876672)) -+1235: --end of the loop-- -[d4bd8bed59e] jit-log-opt-loop} -[d4ec4cd27f2] {jit-backend-counts -entry 0:261 -TargetToken(2876835872976):261 -TargetToken(2876835873064):2362 -bridge 2876878643352:10 -TargetToken(2876835874912):154 -entry 1:82 -TargetToken(2876835876584):82 -TargetToken(2876835876672):393 -[d4ec4ce4d5c] jit-backend-counts} ++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: p19 = getarrayitem_gc(p9, 4, descr=) ++183: p21 = getarrayitem_gc(p9, 5, descr=) ++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(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] ++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] ++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] ++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') ++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') ++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') ++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') ++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') ++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') ++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') ++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') ++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') ++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') ++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') ++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 @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 @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] ++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-- +[19c476fd6fb4] jit-log-opt-loop} +[19c477229d40] {jit-backend +[19c47726a154] {jit-backend-dump +BACKEND x86_64 +SYS_EXECUTABLE python +CODE_DUMP @7fe7c97fd8c8 +0 48817D50FFFFFF007D2448C7442408FFFFFF0049BB88D87FC9E77F00004C891C2449BB75A27FC9E77F000041FFD349BBA0E267CCE77F00004D8B3B4D8D670149BBA0E267CCE77F00004D89234D8D65014D8B6E084D39EC0F8D000000004D8B7E404F0FB65427184983FA330F84000000004D8D5424014D39EA0F8C0000000048C745580000000048C7451000C6FA0148C74520000000004889E84C8BBC24880000004C8BB424800000004C8B6C24784C8B642470488B5C2468488B6C24604881C498000000C349BB800959CCE77F0000415349BB98D87FC9E77F0000415349BB00A07FC9E77F000041FFE349BBD80B59CCE77F0000415349BBA8D87FC9E77F0000415349BB00A07FC9E77F000041FFE349BB600B59CCE77F0000415349BBB8D87FC9E77F0000415349BB00A07FC9E77F000041FFE3 +[19c47727826a] jit-backend-dump} +[19c477278fc6] {jit-backend-dump +BACKEND x86_64 +SYS_EXECUTABLE python +CODE_DUMP @7fe7c97fd8cc +0 1C000000 +[19c477279d40] jit-backend-dump} +[19c47727a217] {jit-backend-dump +BACKEND x86_64 +SYS_EXECUTABLE python +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 @7fe7c97fd921 +0 69000000 +[19c47727ce56] jit-backend-dump} +[19c47727d5d9] {jit-backend-dump +BACKEND x86_64 +SYS_EXECUTABLE python +CODE_DUMP @7fe7c97fd935 +0 7A000000 +[19c47727deef] jit-backend-dump} +[19c47727e32c] {jit-backend-dump +BACKEND x86_64 +SYS_EXECUTABLE python +CODE_DUMP @7fe7c97fd943 +0 91000000 +[19c47727ec22] jit-backend-dump} +[19c47727f5b2] {jit-backend-dump +BACKEND x86_64 +SYS_EXECUTABLE python +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] +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] ++113: i11 = int_add(i3, 1) ++118: i12 = int_lt(i11, i4) +guard_false(i12, descr=) [i11, p1] ++127: finish(0, descr=) ++198: --end of the loop-- +[19c47728e83a] jit-log-opt-bridge} +[19c4775d7810] {jit-backend +[19c47760e455] {jit-backend-dump +BACKEND x86_64 +SYS_EXECUTABLE python +CODE_DUMP @7fe7c97fda30 +0 48817D50FFFFFF007D2448C7442408FFFFFF0049BB00DA7FC9E77F00004C891C2449BB75A27FC9E77F000041FFD349BBB8E267CCE77F00004D8B3B4D8D6F0149BBB8E267CCE77F00004D892B4D8B6E404F0FB67C15184983FF330F84000000004D8D7A014D8B56084D39D70F8C0000000048C745580000000048C7451000C6FA0148C74520000000004889E84C8BBC24880000004C8BB424800000004C8B6C24784C8B642470488B5C2468488B6C24604881C498000000C349BBC80C59CCE77F0000415349BB10DA7FC9E77F0000415349BB00A07FC9E77F000041FFE349BB300E59CCE77F0000415349BB20DA7FC9E77F0000415349BB00A07FC9E77F000041FFE3 +[19c4776123ca] jit-backend-dump} +[19c477612cb4] {jit-backend-dump +BACKEND x86_64 +SYS_EXECUTABLE python +CODE_DUMP @7fe7c97fda34 +0 1C000000 +[19c47761382f] jit-backend-dump} +[19c477613ce8] {jit-backend-dump +BACKEND x86_64 +SYS_EXECUTABLE python +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 @7fe7c97fda8c +0 58000000 +[19c4776165af] jit-backend-dump} From noreply at buildbot.pypy.org Thu Sep 5 17:09:55 2013 From: noreply at buildbot.pypy.org (vext01) Date: Thu, 5 Sep 2013 17:09:55 +0200 (CEST) Subject: [pypy-commit] jitviewer argparse-collect: Again improve help message. Message-ID: <20130905150955.5297E1C0710@cobra.cs.uni-duesseldorf.de> Author: Edd Barrett Branch: argparse-collect Changeset: r240:5bef5a9b487d Date: 2013-08-31 00:22 +0100 http://bitbucket.org/pypy/jitviewer/changeset/5bef5a9b487d/ Log: Again improve help message. * put common case first. * add help showing how to collect log manually. diff --git a/_jitviewer/app.py b/_jitviewer/app.py --- a/_jitviewer/app.py +++ b/_jitviewer/app.py @@ -3,16 +3,21 @@ DESCR = """Jit Viewer: A web-based browser for PyPy log files""" EPILOG = """ +Typical usage with no existing log file: + + jitviewer.py --collect pypy ... + Typical usage with existing log file: jitviewer.py --log -Typical usage with no existing log file: +where you collected a logfile by setting PYPYLOG, e.g.: - jitviewer.py --collect pypy ... + PYPYLOG=jit-log-opt,jit-backend: pypy arg1 ... argn -By default the script will run a web server, point your browser to +By default jitviewer will run a web server. Point your browser to: http://localhost:5000 + """ import sys From noreply at buildbot.pypy.org Thu Sep 5 17:09:56 2013 From: noreply at buildbot.pypy.org (vext01) Date: Thu, 5 Sep 2013 17:09:56 +0200 (CEST) Subject: [pypy-commit] jitviewer argparse-collect: Unbreak --log and make the user (and programmer) aware of a restriction. Message-ID: <20130905150956.4D1B41C0710@cobra.cs.uni-duesseldorf.de> Author: Edd Barrett Branch: argparse-collect Changeset: r241:aec888070eea Date: 2013-08-31 11:15 +0100 http://bitbucket.org/pypy/jitviewer/changeset/aec888070eea/ Log: Unbreak --log and make the user (and programmer) aware of a restriction. logfile and script source must be in the same place... diff --git a/_jitviewer/app.py b/_jitviewer/app.py --- a/_jitviewer/app.py +++ b/_jitviewer/app.py @@ -15,8 +15,11 @@ PYPYLOG=jit-log-opt,jit-backend: pypy arg1 ... argn -By default jitviewer will run a web server. Point your browser to: -http://localhost:5000 +When using an existing logfile, the source code of the logged script must be +in the same location as the logfile. + +Once invoked, jitviewer will run a web server. By default the the server +listens on http://localhost:5000 """ @@ -202,6 +205,8 @@ """ Collect a log file using pypy """ import tempfile, subprocess + print("Collecting log with: %s" % ' '.join(args)) + # create a temp file, possibly racey, but very unlikey (fd, path) = tempfile.mkstemp(prefix="jitviewer-") os.close(fd) # just the filename we want @@ -237,17 +242,21 @@ args.port = 5000 if args.collect is not None: - if len(args.collect) == 0: - print("*Error: Please specify invokation to collect log") + if len(args.collect) < 2: + print("*Error: Please correctly specify invokation to collect log") sys.exit(1) filename = collect_log(args.collect) + extra_path = os.path.dirname(args.collect[1]) # add dirname of script to extra_path elif args.log is not None: filename = args.log + # preserving behaviour before argparse + # XXX not robust as it could be. Assumes the logfile is in the same + # dir as the source code, may not be the case. + extra_path = os.path.dirname(filename) else: print("*Error: Please specify either --log or --collect") sys.exit(1) - extra_path = os.path.dirname(filename) storage = LoopStorage(extra_path) log, loops = import_log(filename, ParserWithHtmlRepr) From noreply at buildbot.pypy.org Thu Sep 5 17:09:57 2013 From: noreply at buildbot.pypy.org (vext01) Date: Thu, 5 Sep 2013 17:09:57 +0200 (CEST) Subject: [pypy-commit] jitviewer argparse-collect: use argparse.REMAINDER as suggested by richardn. Message-ID: <20130905150957.3E1AD1C0710@cobra.cs.uni-duesseldorf.de> Author: Edd Barrett Branch: argparse-collect Changeset: r242:c8b403159a46 Date: 2013-09-03 17:28 +0100 http://bitbucket.org/pypy/jitviewer/changeset/c8b403159a46/ Log: use argparse.REMAINDER as suggested by richardn. diff --git a/_jitviewer/app.py b/_jitviewer/app.py --- a/_jitviewer/app.py +++ b/_jitviewer/app.py @@ -232,7 +232,7 @@ ) parser.add_argument("-l", "--log", help="specify existing logfile") - parser.add_argument("-c", "--collect", nargs="*", help="collect logfile now", metavar="ARG") + parser.add_argument("-c", "--collect", nargs=argparse.REMAINDER, help="collect logfile now", metavar="ARG") parser.add_argument("-p", "--port", help="select HTTP port", type=int) parser.add_argument("-q", "--qt", action="store_true", help="use embedded QT browser") From noreply at buildbot.pypy.org Thu Sep 5 17:09:58 2013 From: noreply at buildbot.pypy.org (vext01) Date: Thu, 5 Sep 2013 17:09:58 +0200 (CEST) Subject: [pypy-commit] jitviewer argparse-collect: Check that we are running under PyPy. Message-ID: <20130905150958.31FDB1C0710@cobra.cs.uni-duesseldorf.de> Author: Edd Barrett Branch: argparse-collect Changeset: r243:259239bc7fe1 Date: 2013-09-05 13:12 +0100 http://bitbucket.org/pypy/jitviewer/changeset/259239bc7fe1/ Log: Check that we are running under PyPy. "< arigato> for example I think that jitviewer doesn't work on CPython" diff --git a/bin/jitviewer.py b/bin/jitviewer.py --- a/bin/jitviewer.py +++ b/bin/jitviewer.py @@ -6,5 +6,10 @@ pythonpath = os.path.dirname(os.path.dirname(script_path)) sys.path.append(pythonpath) +# Check we are running with PyPy +if "pypy" not in os.path.basename(sys.executable): + print("error: jitviewer must be run with PyPy") + sys.exit(1) + from _jitviewer.app import main main(sys.argv) From noreply at buildbot.pypy.org Thu Sep 5 17:10:00 2013 From: noreply at buildbot.pypy.org (vext01) Date: Thu, 5 Sep 2013 17:10:00 +0200 (CEST) Subject: [pypy-commit] jitviewer argparse-collect: Use the same pypy interpreter that jitviewer is run under when collecting logs. Message-ID: <20130905151000.1CD071C0710@cobra.cs.uni-duesseldorf.de> Author: Edd Barrett Branch: argparse-collect Changeset: r244:a69a3358ced8 Date: 2013-09-05 13:22 +0100 http://bitbucket.org/pypy/jitviewer/changeset/a69a3358ced8/ Log: Use the same pypy interpreter that jitviewer is run under when collecting logs. As suggested by Armin Rigo. diff --git a/_jitviewer/app.py b/_jitviewer/app.py --- a/_jitviewer/app.py +++ b/_jitviewer/app.py @@ -5,7 +5,7 @@ EPILOG = """ Typical usage with no existing log file: - jitviewer.py --collect pypy ... + jitviewer.py --collect ... Typical usage with existing log file: @@ -214,7 +214,7 @@ # possibly make this configurable if someone asks... os.environ["PYPYLOG"] = "jit-log-opt,jit-backend:%s" % (path, ) print("Collecting log in '%s'..." % path) - p = subprocess.Popen(args, env=os.environ).communicate() + p = subprocess.Popen([sys.executable] + args, env=os.environ).communicate() # We don't check the return status. The user may want to see traces # for a failing program! @@ -242,11 +242,11 @@ args.port = 5000 if args.collect is not None: - if len(args.collect) < 2: + if len(args.collect) < 1: print("*Error: Please correctly specify invokation to collect log") sys.exit(1) filename = collect_log(args.collect) - extra_path = os.path.dirname(args.collect[1]) # add dirname of script to extra_path + extra_path = os.path.dirname(args.collect[0]) # add dirname of script to extra_path elif args.log is not None: filename = args.log # preserving behaviour before argparse From noreply at buildbot.pypy.org Thu Sep 5 17:10:01 2013 From: noreply at buildbot.pypy.org (vext01) Date: Thu, 5 Sep 2013 17:10:01 +0200 (CEST) Subject: [pypy-commit] jitviewer argparse-collect: Remove existing check for pypy as it is now checked earlier. Message-ID: <20130905151001.1CEF71C0710@cobra.cs.uni-duesseldorf.de> Author: Edd Barrett Branch: argparse-collect Changeset: r245:96c76bb088d6 Date: 2013-09-05 13:33 +0100 http://bitbucket.org/pypy/jitviewer/changeset/96c76bb088d6/ Log: Remove existing check for pypy as it is now checked earlier. diff --git a/_jitviewer/app.py b/_jitviewer/app.py --- a/_jitviewer/app.py +++ b/_jitviewer/app.py @@ -1,4 +1,5 @@ #!/usr/bin/env pypy +from _jitviewer.misc import failout DESCR = """Jit Viewer: A web-based browser for PyPy log files""" @@ -221,10 +222,6 @@ return os.path.abspath(path) def main(argv, run_app=True): - if not '__pypy__' in sys.builtin_module_names: - print "Please run it using pypy-c" - sys.exit(1) - parser = argparse.ArgumentParser( description = DESCR, epilog = EPILOG, diff --git a/_jitviewer/misc.py b/_jitviewer/misc.py new file mode 100644 --- /dev/null +++ b/_jitviewer/misc.py @@ -0,0 +1,5 @@ +import sys + +def failout(msg, exit_status = 1): + print("error: %s" % (msg, )) + sys.exit(exit_status) diff --git a/bin/jitviewer.py b/bin/jitviewer.py --- a/bin/jitviewer.py +++ b/bin/jitviewer.py @@ -6,10 +6,10 @@ pythonpath = os.path.dirname(os.path.dirname(script_path)) sys.path.append(pythonpath) -# Check we are running with PyPy -if "pypy" not in os.path.basename(sys.executable): - print("error: jitviewer must be run with PyPy") - sys.exit(1) +# Check we are running with PyPy first. +if not '__pypy__' in sys.builtin_module_names: + from _jitviewer.misc import failout + failout("jitviewer must be run with PyPy") from _jitviewer.app import main main(sys.argv) From noreply at buildbot.pypy.org Thu Sep 5 17:10:02 2013 From: noreply at buildbot.pypy.org (vext01) Date: Thu, 5 Sep 2013 17:10:02 +0200 (CEST) Subject: [pypy-commit] jitviewer argparse-collect: unify trival error message via misc.failout() Message-ID: <20130905151002.0F91D1C0710@cobra.cs.uni-duesseldorf.de> Author: Edd Barrett Branch: argparse-collect Changeset: r246:0dbda567e412 Date: 2013-09-05 13:35 +0100 http://bitbucket.org/pypy/jitviewer/changeset/0dbda567e412/ Log: unify trival error message via misc.failout() diff --git a/_jitviewer/app.py b/_jitviewer/app.py --- a/_jitviewer/app.py +++ b/_jitviewer/app.py @@ -1,5 +1,5 @@ #!/usr/bin/env pypy -from _jitviewer.misc import failout +from misc import failout DESCR = """Jit Viewer: A web-based browser for PyPy log files""" @@ -240,8 +240,7 @@ if args.collect is not None: if len(args.collect) < 1: - print("*Error: Please correctly specify invokation to collect log") - sys.exit(1) + failout("please correctly specify invokation to collect log") filename = collect_log(args.collect) extra_path = os.path.dirname(args.collect[0]) # add dirname of script to extra_path elif args.log is not None: @@ -251,8 +250,7 @@ # dir as the source code, may not be the case. extra_path = os.path.dirname(filename) else: - print("*Error: Please specify either --log or --collect") - sys.exit(1) + failout("please specify either --log or --collect") storage = LoopStorage(extra_path) From noreply at buildbot.pypy.org Thu Sep 5 17:10:03 2013 From: noreply at buildbot.pypy.org (vext01) Date: Thu, 5 Sep 2013 17:10:03 +0200 (CEST) Subject: [pypy-commit] jitviewer argparse-collect: unify a couple more error messages Message-ID: <20130905151003.17A9F1C0710@cobra.cs.uni-duesseldorf.de> Author: Edd Barrett Branch: argparse-collect Changeset: r247:7198640c99ae Date: 2013-09-05 13:45 +0100 http://bitbucket.org/pypy/jitviewer/changeset/7198640c99ae/ Log: unify a couple more error messages diff --git a/_jitviewer/app.py b/_jitviewer/app.py --- a/_jitviewer/app.py +++ b/_jitviewer/app.py @@ -36,12 +36,12 @@ try: import pypy except ImportError: - raise ImportError('Could not import pypy module, make sure to ' + failout('Could not import pypy module, make sure to ' 'add the pypy module to PYTHONPATH') import jinja2 if jinja2.__version__ < '2.6': - raise ImportError("Required jinja version is 2.6 (the git tip), older versions might segfault PyPy") + failout("Required jinja version is 2.6 (the git tip), older versions might segfault PyPy") import flask import inspect From noreply at buildbot.pypy.org Thu Sep 5 17:10:04 2013 From: noreply at buildbot.pypy.org (arigo) Date: Thu, 5 Sep 2013 17:10:04 +0200 (CEST) Subject: [pypy-commit] jitviewer default: Merged in vext01/jitviewer/argparse-collect (pull request #5) Message-ID: <20130905151004.35E3E1C0710@cobra.cs.uni-duesseldorf.de> Author: Armin Rigo Branch: Changeset: r248:fd0b3dbac5c5 Date: 2013-09-05 17:09 +0200 http://bitbucket.org/pypy/jitviewer/changeset/fd0b3dbac5c5/ Log: Merged in vext01/jitviewer/argparse-collect (pull request #5) Improve jitviewer usability. diff --git a/_jitviewer/app.py b/_jitviewer/app.py --- a/_jitviewer/app.py +++ b/_jitviewer/app.py @@ -1,29 +1,32 @@ #!/usr/bin/env pypy -""" A web-based browser of your log files. Run by +from misc import failout - jitviewer.py [port] [--qt] +DESCR = """Jit Viewer: A web-based browser for PyPy log files""" -By default the script will run a web server, point your browser to -http://localhost:5000 +EPILOG = """ +Typical usage with no existing log file: -If you pass --qt, this script will also start a lightweight PyQT/QWebKit based -browser pointing at the jitviewer. This assumes that CPython is installed in -/usr/bin/python, and that PyQT with WebKit support is installed. + jitviewer.py --collect ... -Demo logfile available in this directory as 'log'. +Typical usage with existing log file: -To produce the logfile for your program, run: + jitviewer.py --log - PYPYLOG=jit-log-opt,jit-backend:mylogfile.pypylog pypy myapp.py +where you collected a logfile by setting PYPYLOG, e.g.: + + PYPYLOG=jit-log-opt,jit-backend: pypy arg1 ... argn + +When using an existing logfile, the source code of the logged script must be +in the same location as the logfile. + +Once invoked, jitviewer will run a web server. By default the the server +listens on http://localhost:5000 + """ import sys import os.path - -try: - import _jitviewer -except ImportError: - sys.path.insert(0, os.path.abspath(os.path.join(__file__, '..', '..'))) +import argparse try: import pypy @@ -33,12 +36,12 @@ try: import pypy except ImportError: - raise ImportError('Could not import pypy module, make sure to ' + failout('Could not import pypy module, make sure to ' 'add the pypy module to PYTHONPATH') import jinja2 if jinja2.__version__ < '2.6': - raise ImportError("Required jinja version is 2.6 (the git tip), older versions might segfault PyPy") + failout("Required jinja version is 2.6 (the git tip), older versions might segfault PyPy") import flask import inspect @@ -199,26 +202,58 @@ orig___init__(self2, *args, **kwds) BaseServer.__init__ = __init__ +def collect_log(args): + """ Collect a log file using pypy """ + import tempfile, subprocess + + print("Collecting log with: %s" % ' '.join(args)) + + # create a temp file, possibly racey, but very unlikey + (fd, path) = tempfile.mkstemp(prefix="jitviewer-") + os.close(fd) # just the filename we want + + # possibly make this configurable if someone asks... + os.environ["PYPYLOG"] = "jit-log-opt,jit-backend:%s" % (path, ) + print("Collecting log in '%s'..." % path) + p = subprocess.Popen([sys.executable] + args, env=os.environ).communicate() + + # We don't check the return status. The user may want to see traces + # for a failing program! + return os.path.abspath(path) + def main(argv, run_app=True): - if not '__pypy__' in sys.builtin_module_names: - print "Please run it using pypy-c" - sys.exit(1) - # - server_mode = True - if '--qt' in argv: - server_mode = False - argv.remove('--qt') - # - if len(argv) != 2 and len(argv) != 3: - print __doc__ - sys.exit(1) - filename = argv[1] - extra_path = os.path.dirname(filename) - if len(argv) != 3: - port = 5000 + parser = argparse.ArgumentParser( + description = DESCR, + epilog = EPILOG, + formatter_class=argparse.RawDescriptionHelpFormatter + ) + + parser.add_argument("-l", "--log", help="specify existing logfile") + parser.add_argument("-c", "--collect", nargs=argparse.REMAINDER, help="collect logfile now", metavar="ARG") + parser.add_argument("-p", "--port", help="select HTTP port", type=int) + parser.add_argument("-q", "--qt", action="store_true", help="use embedded QT browser") + + args = parser.parse_args() + + if args.port is None: + args.port = 5000 + + if args.collect is not None: + if len(args.collect) < 1: + failout("please correctly specify invokation to collect log") + filename = collect_log(args.collect) + extra_path = os.path.dirname(args.collect[0]) # add dirname of script to extra_path + elif args.log is not None: + filename = args.log + # preserving behaviour before argparse + # XXX not robust as it could be. Assumes the logfile is in the same + # dir as the source code, may not be the case. + extra_path = os.path.dirname(filename) else: - port = int(argv[2]) + failout("please specify either --log or --collect") + storage = LoopStorage(extra_path) + log, loops = import_log(filename, ParserWithHtmlRepr) parse_log_counts(extract_category(log, 'jit-backend-count'), loops) storage.loops = [loop for loop in loops @@ -231,12 +266,12 @@ app.route('/loop')(server.loop) if run_app: def run(): - app.run(use_reloader=bool(os.environ.get('JITVIEWER_USE_RELOADER', True)), host='0.0.0.0', port=port) + app.run(use_reloader=bool(os.environ.get('JITVIEWER_USE_RELOADER', False)), host='0.0.0.0', port=args.port) - if server_mode: + if not args.qt: run() else: - url = "http://localhost:%d/" % port + url = "http://localhost:%d/" % args.port run_server_and_browser(app, run, url, filename) else: return app diff --git a/_jitviewer/misc.py b/_jitviewer/misc.py new file mode 100644 --- /dev/null +++ b/_jitviewer/misc.py @@ -0,0 +1,5 @@ +import sys + +def failout(msg, exit_status = 1): + print("error: %s" % (msg, )) + sys.exit(exit_status) diff --git a/_jitviewer/static/style.css b/_jitviewer/static/style.css --- a/_jitviewer/static/style.css +++ b/_jitviewer/static/style.css @@ -232,17 +232,16 @@ font-weight: bold; } +.menu { + background: #cccccc; + text-color: red; +} + +h1 { + padding: 10px 10px 10px 10px; + background: #ffcc66; + font-size: 25px; +} + /* End of Formatting -----------------------------------------*/ - - - - - - - - - - - - diff --git a/_jitviewer/templates/index.html b/_jitviewer/templates/index.html --- a/_jitviewer/templates/index.html +++ b/_jitviewer/templates/index.html @@ -19,15 +19,18 @@
    - Menu
    + Show assembler [a]
    Show bytecode position [b]
    +

    JIT Viewer

    +
    Filter [/]:
    diff --git a/bin/jitviewer.py b/bin/jitviewer.py --- a/bin/jitviewer.py +++ b/bin/jitviewer.py @@ -1,4 +1,15 @@ #!/usr/bin/env pypy import sys +import os.path + +script_path = os.path.abspath(__file__) +pythonpath = os.path.dirname(os.path.dirname(script_path)) +sys.path.append(pythonpath) + +# Check we are running with PyPy first. +if not '__pypy__' in sys.builtin_module_names: + from _jitviewer.misc import failout + failout("jitviewer must be run with PyPy") + from _jitviewer.app import main main(sys.argv) From noreply at buildbot.pypy.org Thu Sep 5 17:12:32 2013 From: noreply at buildbot.pypy.org (arigo) Date: Thu, 5 Sep 2013 17:12:32 +0200 (CEST) Subject: [pypy-commit] pypy stmgc-c4: Fix Message-ID: <20130905151232.0A94B1C36AC@cobra.cs.uni-duesseldorf.de> Author: Armin Rigo Branch: stmgc-c4 Changeset: r66807:3f2fd641dfc7 Date: 2013-09-05 17:11 +0200 http://bitbucket.org/pypy/pypy/changeset/3f2fd641dfc7/ Log: Fix 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 @@ -627,7 +627,7 @@ self.cpu.profile_agent.native_code_written(name, rawstart, full_size) return AsmInfo(ops_offset, rawstart + looppos, - size_excluding_failure_stuff - looppos), operations + size_excluding_failure_stuff - looppos) @rgc.no_release_gil def assemble_bridge(self, faildescr, inputargs, operations, @@ -677,8 +677,7 @@ self.cpu.profile_agent.native_code_written(name, rawstart, fullsize) return AsmInfo(ops_offset, startpos + rawstart, - codeendpos - startpos), operations - + codeendpos - startpos) def write_pending_failure_recoveries(self): # for each pending guard, generate the code of the recovery stub From noreply at buildbot.pypy.org Thu Sep 5 17:27:21 2013 From: noreply at buildbot.pypy.org (arigo) Date: Thu, 5 Sep 2013 17:27:21 +0200 (CEST) Subject: [pypy-commit] pypy default: (vext01) Issue 1531 Message-ID: <20130905152721.27BCB1D22BD@cobra.cs.uni-duesseldorf.de> Author: Armin Rigo Branch: Changeset: r66808:f4af061522f7 Date: 2013-09-05 17:26 +0200 http://bitbucket.org/pypy/pypy/changeset/f4af061522f7/ Log: (vext01) Issue 1531 Add OpenBSD specific paths to tkinter module. diff --git a/lib_pypy/_tkinter/tklib.py b/lib_pypy/_tkinter/tklib.py --- a/lib_pypy/_tkinter/tklib.py +++ b/lib_pypy/_tkinter/tklib.py @@ -1,6 +1,7 @@ # C bindings with libtcl and libtk. from cffi import FFI +import sys tkffi = FFI() @@ -102,6 +103,17 @@ int Tk_GetNumMainWindows(); """) +# XXX find a better way to detect paths +# XXX pick up CPPFLAGS and LDFLAGS and add to these paths? +if sys.platform.startswith("openbsd"): + incdirs = ['/usr/local/include/tcl8.5', '/usr/local/include/tk8.5', '/usr/X11R6/include'] + linklibs = ['tk85', 'tcl85'] + libdirs = ['/usr/local/lib', '/usr/X11R6/lib'] +else: + incdirs=['/usr/include/tcl'], + linklibs=['tcl', 'tk'], + libdirs = [] + tklib = tkffi.verify(""" #include #include @@ -109,6 +121,7 @@ char *get_tk_version() { return TK_VERSION; } char *get_tcl_version() { return TCL_VERSION; } """, -include_dirs=['/usr/include/tcl'], -libraries=['tcl', 'tk'], +include_dirs=incdirs, +libraries=linklibs, +library_dirs = libdirs ) From noreply at buildbot.pypy.org Thu Sep 5 17:34:30 2013 From: noreply at buildbot.pypy.org (arigo) Date: Thu, 5 Sep 2013 17:34:30 +0200 (CEST) Subject: [pypy-commit] pypy stmgc-c4: Fix test Message-ID: <20130905153430.064731D2305@cobra.cs.uni-duesseldorf.de> Author: Armin Rigo Branch: stmgc-c4 Changeset: r66809:2d39ff5c7e6b Date: 2013-09-05 17:33 +0200 http://bitbucket.org/pypy/pypy/changeset/2d39ff5c7e6b/ Log: Fix 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 @@ -2128,7 +2128,7 @@ jit_wb_if_flag = 4096 jit_wb_if_flag_byteofs = struct.pack("i", 4096).index('\x10') jit_wb_if_flag_singlebyte = 0x10 - def get_write_barrier_fn(self, cpu, returns_modified_object): + def get_barrier_fn(self, cpu, returns_modified_object): assert self.returns_modified_object == returns_modified_object return funcbox.getint() # @@ -2151,6 +2151,7 @@ assert record == [] def test_cond_call_gc_wb_stm_returns_modified_object(self): + py.test.skip("XXX rethink this test") def func_void(a): record.append(a) return t @@ -2165,7 +2166,7 @@ jit_wb_if_flag = 4096 jit_wb_if_flag_byteofs = struct.pack("i", 4096).index('\x10') jit_wb_if_flag_singlebyte = 0x10 - def get_write_barrier_fn(self, cpu, returns_modified_object): + def get_barrier_fn(self, cpu, returns_modified_object): assert self.returns_modified_object == returns_modified_object return funcbox.getint() # @@ -2185,14 +2186,15 @@ operations = [ ResOperation(rop.COND_CALL_GC_WB, [p0], None, descr=WriteBarrierDescr()), - ResOperation(rop.FINISH, [p0], None, descr=BasicFinalDescr(0)) + ResOperation(rop.FINISH, [p0], None, descr=BasicFinalDescr(4)) ] inputargs = [p0] looptoken = JitCellToken() self.cpu.compile_loop(None, inputargs, operations, looptoken) - fail = self.cpu.execute_token(looptoken, sgcref) - assert fail.identifier == 1 - res = self.cpu.get_latest_value_ref(0) + deadframe = self.cpu.execute_token(looptoken, sgcref) + fail = self.cpu.get_latest_descr(deadframe) + assert fail.identifier == 4 + res = self.cpu.get_ref_value(deadframe, 0) if cond: assert record == [s] assert res == tgcref From noreply at buildbot.pypy.org Thu Sep 5 17:36:41 2013 From: noreply at buildbot.pypy.org (arigo) Date: Thu, 5 Sep 2013 17:36:41 +0200 (CEST) Subject: [pypy-commit] pypy stmgc-c4: More fixes Message-ID: <20130905153641.AD8BD1D2305@cobra.cs.uni-duesseldorf.de> Author: Armin Rigo Branch: stmgc-c4 Changeset: r66810:5272acf6b7d4 Date: 2013-09-05 17:36 +0200 http://bitbucket.org/pypy/pypy/changeset/5272acf6b7d4/ Log: More fixes 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 @@ -2216,9 +2216,11 @@ jit_wb_if_flag_byteofs = struct.pack("i", 4096).index('\x10') jit_wb_if_flag_singlebyte = 0x10 jit_wb_cards_set = 0 # <= without card marking - def get_write_barrier_fn(self, cpu, returns_modified_object): + def get_barrier_fn(self, cpu, returns_modified_object): assert self.returns_modified_object == returns_modified_object return funcbox.getint() + def get_barrier_from_array_fn(self, cpu): + return 0 # for cond in [False, True]: value = random.randrange(-sys.maxint, sys.maxint) @@ -2267,7 +2269,7 @@ jit_wb_cards_set_byteofs = struct.pack("i", 32768).index('\x80') jit_wb_cards_set_singlebyte = -0x80 jit_wb_card_page_shift = 7 - def get_write_barrier_from_array_fn(self, cpu): + def get_barrier_from_array_fn(self, cpu): return funcbox.getint() # for BoxIndexCls in [BoxInt, ConstInt]*3: From noreply at buildbot.pypy.org Thu Sep 5 17:38:24 2013 From: noreply at buildbot.pypy.org (arigo) Date: Thu, 5 Sep 2013 17:38:24 +0200 (CEST) Subject: [pypy-commit] pypy stmgc-c4: Fix Message-ID: <20130905153824.565411D2305@cobra.cs.uni-duesseldorf.de> Author: Armin Rigo Branch: stmgc-c4 Changeset: r66811:ba68bc62d2f3 Date: 2013-09-05 17:37 +0200 http://bitbucket.org/pypy/pypy/changeset/ba68bc62d2f3/ Log: Fix diff --git a/rpython/jit/backend/x86/test/test_runner.py b/rpython/jit/backend/x86/test/test_runner.py --- a/rpython/jit/backend/x86/test/test_runner.py +++ b/rpython/jit/backend/x86/test/test_runner.py @@ -427,8 +427,8 @@ debug._log = None # assert ops_offset is looptoken._x86_ops_offset - # 2*(getfield_raw/int_add/setfield_raw) + ops + None - assert len(ops_offset) == 2*3 + len(operations) + 1 + # 2*[INCREMENT_DEBUG_COUNTER] + ops + None + assert len(ops_offset) == 2 + len(operations) + 1 assert (ops_offset[operations[0]] <= ops_offset[operations[1]] <= ops_offset[operations[2]] <= From noreply at buildbot.pypy.org Thu Sep 5 17:53:29 2013 From: noreply at buildbot.pypy.org (arigo) Date: Thu, 5 Sep 2013 17:53:29 +0200 (CEST) Subject: [pypy-commit] pypy stmgc-c4: Fix Message-ID: <20130905155329.4BBA51C0710@cobra.cs.uni-duesseldorf.de> Author: Armin Rigo Branch: stmgc-c4 Changeset: r66812:c7ee1015d51e Date: 2013-09-05 17:52 +0200 http://bitbucket.org/pypy/pypy/changeset/c7ee1015d51e/ Log: Fix 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 @@ -92,6 +92,8 @@ start = int(adr.strip(":"), 16) ofs = int(adr.strip(":"), 16) # add symbols to addresses: + if symbols is None: + symbols = {} for addr in lineaddresses(v): sym = symbols.get(addr) if sym: From noreply at buildbot.pypy.org Thu Sep 5 20:37:35 2013 From: noreply at buildbot.pypy.org (rlamy) Date: Thu, 5 Sep 2013 20:37:35 +0200 (CEST) Subject: [pypy-commit] pypy less-stringly-ops: Replace uses of ImplicitOperationError with a RaiseImplicit exception Message-ID: <20130905183735.198511C0710@cobra.cs.uni-duesseldorf.de> Author: Ronan Lamy Branch: less-stringly-ops Changeset: r66813:e675c5b7eb86 Date: 2013-09-05 19:36 +0100 http://bitbucket.org/pypy/pypy/changeset/e675c5b7eb86/ Log: Replace uses of ImplicitOperationError with a RaiseImplicit exception RaiseImplicit is similar to Return and wraps an FSException object. Wrapped exceptions are now always instances of FSException. diff --git a/rpython/flowspace/flowcontext.py b/rpython/flowspace/flowcontext.py --- a/rpython/flowspace/flowcontext.py +++ b/rpython/flowspace/flowcontext.py @@ -34,8 +34,9 @@ def __init__(self, value): self.value = value -class ImplicitOperationError(FSException): - pass +class RaiseImplicit(Exception): + def __init__(self, value): + self.value = value class BytecodeCorruption(Exception): pass @@ -215,7 +216,7 @@ if isinstance(egg.last_exception, Constant): w_exc_cls = egg.last_exception assert not isinstance(w_exc_cls.value, list) - raise ImplicitOperationError(w_exc_cls, w_exc_value) + raise RaiseImplicit(FSException(w_exc_cls, w_exc_value)) # ____________________________________________________________ @@ -448,11 +449,6 @@ def guessexception(self, exceptions, force=False): """ Catch possible exceptions implicitly. - - If the FSException is not caught in the same function, it will - produce an exception-raising return block in the flow graph. Note that - even if the interpreter re-raises the exception, it will not be the - same ImplicitOperationError instance internally. """ if not force and not any(isinstance(block, (ExceptBlock, FinallyBlock)) for block in self.blockstack): @@ -478,9 +474,10 @@ next_pos = self.handle_bytecode(next_pos) self.recorder.final_state = self.getstate(next_pos) - except ImplicitOperationError, e: - if isinstance(e.w_type, Constant): - exc_cls = e.w_type.value + except RaiseImplicit as e: + w_exc = e.value + if isinstance(w_exc.w_type, Constant): + exc_cls = w_exc.w_type.value else: exc_cls = Exception msg = "implicit %s shouldn't occur" % exc_cls.__name__ @@ -567,6 +564,8 @@ try: res = getattr(self, methodname)(oparg) return res if res is not None else next_instr + except RaiseImplicit as e: + return SImplicitException(e.value).unroll(self) except FSException, operr: return self.handle_operation_error(operr) @@ -639,12 +638,7 @@ space = self.space if nbargs == 0: if self.last_exception is not None: - operr = self.last_exception - if isinstance(operr, ImplicitOperationError): - # re-raising an implicit operation makes it an explicit one - operr = FSException(operr.w_type, operr.w_value) - self.last_exception = operr - raise operr + raise self.last_exception else: raise const(TypeError( "raise: no active exception to re-raise")) @@ -781,7 +775,15 @@ w_iterator = self.peekvalue() try: w_nextitem = self.space.next(w_iterator) - except FSException, e: + except RaiseImplicit as e: + w_exc = e.value + if not self.space.exception_match(w_exc.w_type, + self.space.w_StopIteration): + raise + # iterator exhausted + self.popvalue() + return target + except FSException as e: if not self.space.exception_match(e.w_type, self.space.w_StopIteration): raise # iterator exhausted @@ -1194,6 +1196,11 @@ def state_pack_variables(w_type, w_value): return SApplicationException(FSException(w_type, w_value)) +class SImplicitException(SApplicationException): + """Signals an exception raised implicitly""" + def nomoreblocks(self): + raise RaiseImplicit(self.operr) + class SBreakLoop(SuspendedUnroller): """Signals a 'break' statement.""" From noreply at buildbot.pypy.org Thu Sep 5 22:41:54 2013 From: noreply at buildbot.pypy.org (arigo) Date: Thu, 5 Sep 2013 22:41:54 +0200 (CEST) Subject: [pypy-commit] pypy stmgc-c4: the call to report_abort_info() is disabled for now because it's buggy Message-ID: <20130905204154.756381C0EE9@cobra.cs.uni-duesseldorf.de> Author: Armin Rigo Branch: stmgc-c4 Changeset: r66814:35e42cb1574d Date: 2013-09-05 22:39 +0200 http://bitbucket.org/pypy/pypy/changeset/35e42cb1574d/ Log: the call to report_abort_info() is disabled for now because it's buggy diff --git a/lib_pypy/transaction.py b/lib_pypy/transaction.py --- a/lib_pypy/transaction.py +++ b/lib_pypy/transaction.py @@ -229,13 +229,15 @@ while True: with signals_enabled: with atomic: - info = last_abort_info() - if info is None: + # XXX the call to report_abort_info() is disabled for + # XXX now because it's buggy + #info = last_abort_info() + #if info is None: if not got_exception: f(*args, **kwds) # else return early if already an exc to reraise return - report_abort_info(info) + #report_abort_info(info) except: got_exception[:] = sys.exc_info() From noreply at buildbot.pypy.org Thu Sep 5 22:42:56 2013 From: noreply at buildbot.pypy.org (arigo) Date: Thu, 5 Sep 2013 22:42:56 +0200 (CEST) Subject: [pypy-commit] pypy no-release-gil: Ready for merging Message-ID: <20130905204256.B9ACF1C36AC@cobra.cs.uni-duesseldorf.de> Author: Armin Rigo Branch: no-release-gil Changeset: r66815:8b7ae9a8c054 Date: 2013-08-30 12:46 +0200 http://bitbucket.org/pypy/pypy/changeset/8b7ae9a8c054/ Log: Ready for merging From noreply at buildbot.pypy.org Thu Sep 5 22:42:58 2013 From: noreply at buildbot.pypy.org (arigo) Date: Thu, 5 Sep 2013 22:42:58 +0200 (CEST) Subject: [pypy-commit] pypy default: Merge branch 'no-release-gil': Message-ID: <20130905204258.AFAB61C36AC@cobra.cs.uni-duesseldorf.de> Author: Armin Rigo Branch: Changeset: r66816:c86260fa25c1 Date: 2013-08-30 12:47 +0200 http://bitbucket.org/pypy/pypy/changeset/c86260fa25c1/ Log: Merge branch 'no-release-gil': Adds @rgc.no_release_gil and puts it around the JIT assembler functions diff --git a/pypy/interpreter/baseobjspace.py b/pypy/interpreter/baseobjspace.py --- a/pypy/interpreter/baseobjspace.py +++ b/pypy/interpreter/baseobjspace.py @@ -77,12 +77,12 @@ raise NotImplementedError("only for interp-level user subclasses " "from typedef.py") - def getname(self, space, default='?'): + def getname(self, space): try: return space.str_w(space.getattr(self, space.wrap('__name__'))) except OperationError, e: if e.match(space, space.w_TypeError) or e.match(space, space.w_AttributeError): - return default + return '?' raise def getaddrstring(self, space): diff --git a/pypy/interpreter/function.py b/pypy/interpreter/function.py --- a/pypy/interpreter/function.py +++ b/pypy/interpreter/function.py @@ -482,17 +482,16 @@ space.abstract_isinstance_w(w_firstarg, self.w_class)): pass # ok else: - clsdescr = self.w_class.getname(space, "") - if clsdescr: + clsdescr = self.w_class.getname(space) + if clsdescr and clsdescr != '?': clsdescr += " instance" else: clsdescr = "instance" if w_firstarg is None: instdescr = "nothing" else: - instname = space.abstract_getclass(w_firstarg).getname(space, - "") - if instname: + instname = space.abstract_getclass(w_firstarg).getname(space) + if instname and instname != '?': instdescr = instname + " instance" else: instdescr = "instance" diff --git a/pypy/interpreter/test/test_argument.py b/pypy/interpreter/test/test_argument.py --- a/pypy/interpreter/test/test_argument.py +++ b/pypy/interpreter/test/test_argument.py @@ -128,7 +128,7 @@ def type(self, obj): class Type: - def getname(self, space, default='?'): + def getname(self, space): return type(obj).__name__ return Type() 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 @@ -175,8 +175,8 @@ state = '; dead' else: typename = space.type(w_obj).getname(space) - objname = w_obj.getname(space, '') - if objname: + objname = w_obj.getname(space) + if objname and objname != '?': state = "; to '%s' (%s)" % (typename, objname) else: state = "; to '%s'" % (typename,) diff --git a/pypy/objspace/descroperation.py b/pypy/objspace/descroperation.py --- a/pypy/objspace/descroperation.py +++ b/pypy/objspace/descroperation.py @@ -597,8 +597,8 @@ if num1 != num2: lt = num1 # if obj1 is a number, it is Lower Than obj2 else: - name1 = w_typ1.getname(space, "") - name2 = w_typ2.getname(space, "") + name1 = w_typ1.getname(space) + name2 = w_typ2.getname(space) if name1 != name2: lt = name1 < name2 else: 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 @@ -494,6 +494,12 @@ else: return w_self.name + def getname(w_self, space): + name = w_self.name + if name is None: + name = '?' + return name + def add_subclass(w_self, w_subclass): space = w_self.space if not space.config.translation.rweakref: 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 @@ -29,6 +29,7 @@ from rpython.rtyper.annlowlevel import llhelper, cast_instance_to_gcref from rpython.rtyper.lltypesystem import lltype, rffi from rpython.jit.backend.arm import callbuilder +from rpython.rtyper.lltypesystem.lloperation import llop class AssemblerARM(ResOpAssembler): @@ -1488,7 +1489,9 @@ def not_implemented(msg): - os.write(2, '[ARM/asm] %s\n' % msg) + msg = '[ARM/asm] %s\n' % msg + if we_are_translated(): + llop.debug_print(lltype.Void, msg) raise NotImplementedError(msg) 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 @@ -2,6 +2,8 @@ from rpython.jit.metainterp.history import Const, Box, REF, JitCellToken from rpython.rlib.objectmodel import we_are_translated, specialize from rpython.jit.metainterp.resoperation import rop +from rpython.rtyper.lltypesystem import lltype +from rpython.rtyper.lltypesystem.lloperation import llop try: from collections import OrderedDict @@ -753,5 +755,7 @@ def not_implemented(msg): - os.write(2, '[llsupport/regalloc] %s\n' % msg) + msg = '[llsupport/regalloc] %s\n' % msg + if we_are_translated(): + llop.debug_print(lltype.Void, msg) raise NotImplementedError(msg) 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 @@ -434,6 +434,7 @@ else: self.wb_slowpath[withcards + 2 * withfloats] = rawstart + @rgc.no_release_gil def assemble_loop(self, logger, loopname, inputargs, operations, looptoken, log): '''adds the following attributes to looptoken: @@ -513,6 +514,7 @@ return AsmInfo(ops_offset, rawstart + looppos, size_excluding_failure_stuff - looppos) + @rgc.no_release_gil def assemble_bridge(self, logger, faildescr, inputargs, operations, original_loop_token, log): if not we_are_translated(): @@ -2388,7 +2390,9 @@ return AddressLoc(ImmedLoc(addr), imm0, 0, 0) def not_implemented(msg): - os.write(2, '[x86/asm] %s\n' % msg) + msg = '[x86/asm] %s\n' % msg + if we_are_translated(): + llop.debug_print(lltype.Void, msg) raise NotImplementedError(msg) cond_call_register_arguments = [edi, esi, edx, ecx] 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 @@ -28,6 +28,7 @@ from rpython.rlib.rarithmetic import r_longlong, r_uint from rpython.rtyper.annlowlevel import cast_instance_to_gcref from rpython.rtyper.lltypesystem import lltype, rffi, rstr +from rpython.rtyper.lltypesystem.lloperation import llop class X86RegisterManager(RegisterManager): @@ -1375,7 +1376,9 @@ return base_ofs + WORD * (position + JITFRAME_FIXED_SIZE) def not_implemented(msg): - os.write(2, '[x86/regalloc] %s\n' % msg) + msg = '[x86/regalloc] %s\n' % msg + if we_are_translated(): + llop.debug_print(lltype.Void, msg) raise NotImplementedError(msg) # xxx hack: set a default value for TargetToken._ll_loop_code. 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 @@ -1,6 +1,7 @@ import py from rpython.rtyper.lltypesystem import lltype, llmemory, rffi from rpython.rlib.jit_hooks import LOOP_RUN_CONTAINER +from rpython.rlib import rgc from rpython.jit.backend.x86.assembler import Assembler386 from rpython.jit.backend.x86.regalloc import gpr_reg_mgr_cls, xmm_reg_mgr_cls from rpython.jit.backend.x86.profagent import ProfileAgent @@ -63,10 +64,12 @@ assert self.assembler is not None return RegAlloc(self.assembler, False) + @rgc.no_release_gil def setup_once(self): self.profile_agent.startup() self.assembler.setup_once() + @rgc.no_release_gil def finish_once(self): self.assembler.finish_once() self.profile_agent.shutdown() diff --git a/rpython/rlib/rgc.py b/rpython/rlib/rgc.py --- a/rpython/rlib/rgc.py +++ b/rpython/rlib/rgc.py @@ -262,7 +262,11 @@ keepalive_until_here(newp) return newp - +def no_release_gil(func): + func._dont_inline_ = True + func._no_release_gil_ = True + return func + def no_collect(func): func._dont_inline_ = True func._gc_no_collect_ = True diff --git a/rpython/translator/backendopt/all.py b/rpython/translator/backendopt/all.py --- a/rpython/translator/backendopt/all.py +++ b/rpython/translator/backendopt/all.py @@ -10,6 +10,7 @@ from rpython.translator.backendopt.removeassert import remove_asserts from rpython.translator.backendopt.support import log from rpython.translator.backendopt.storesink import storesink_graph +from rpython.translator.backendopt import gilanalysis from rpython.flowspace.model import checkgraph INLINE_THRESHOLD_FOR_TEST = 33 @@ -138,6 +139,9 @@ for graph in graphs: checkgraph(graph) + gilanalysis.analyze(graphs, translator) + + def constfold(config, graphs): if config.constfold: for graph in graphs: diff --git a/rpython/translator/backendopt/gilanalysis.py b/rpython/translator/backendopt/gilanalysis.py new file mode 100644 --- /dev/null +++ b/rpython/translator/backendopt/gilanalysis.py @@ -0,0 +1,60 @@ +from rpython.translator.backendopt import graphanalyze + +# This is not an optimization. It checks for possible releases of the +# GIL in all graphs starting from rgc.no_release_gil. + + +class GilAnalyzer(graphanalyze.BoolGraphAnalyzer): + + def analyze_direct_call(self, graph, seen=None): + try: + func = graph.func + except AttributeError: + pass + else: + if getattr(func, '_gctransformer_hint_close_stack_', False): + return True + if getattr(func, '_transaction_break_', False): + return True + + return graphanalyze.BoolGraphAnalyzer.analyze_direct_call( + self, graph, seen) + + def analyze_external_call(self, op, seen=None): + funcobj = op.args[0].value._obj + if getattr(funcobj, 'transactionsafe', False): + return False + else: + return False + + def analyze_instantiate_call(self, seen=None): + return False + + def analyze_simple_operation(self, op, graphinfo): + return False + +def analyze(graphs, translator): + gilanalyzer = GilAnalyzer(translator) + for graph in graphs: + func = getattr(graph, 'func', None) + if func and getattr(func, '_no_release_gil_', False): + if gilanalyzer.analyze_direct_call(graph): + # 'no_release_gil' function can release the gil + import cStringIO + err = cStringIO.StringIO() + import sys + prev = sys.stdout + try: + sys.stdout = err + ca = GilAnalyzer(translator) + ca.verbose = True + ca.analyze_direct_call(graph) # print the "traceback" here + sys.stdout = prev + except: + sys.stdout = prev + # ^^^ for the dump of which operation in which graph actually + # causes it to return True + raise Exception("'no_release_gil' function can release the GIL:" + " %s\n%s" % (func, err.getvalue())) + + diff --git a/rpython/translator/backendopt/graphanalyze.py b/rpython/translator/backendopt/graphanalyze.py --- a/rpython/translator/backendopt/graphanalyze.py +++ b/rpython/translator/backendopt/graphanalyze.py @@ -1,6 +1,7 @@ from rpython.rtyper.lltypesystem.lltype import DelayedPointer from rpython.translator.simplify import get_graph from rpython.tool.algo.unionfind import UnionFind +from rpython.rtyper.lltypesystem import rclass class GraphAnalyzer(object): @@ -67,6 +68,9 @@ result, self.analyze_direct_call(graph, seen)) return result + def analyze_instantiate_call(self, seen=None): + return self.top_result() + def analyze_link(self, graph, link): return self.bottom_result() @@ -75,7 +79,7 @@ def compute_graph_info(self, graph): return None - def analyze(self, op, seen=None, graphinfo=None): + def analyze(self, op, seen=None, graphinfo=None, block=None): if op.opname == "direct_call": graph = get_graph(op.args[0], self.translator) if graph is None: @@ -90,6 +94,18 @@ elif op.opname == "indirect_call": graphs = op.args[-1].value if graphs is None: + if block is not None: + v_func = op.args[0] + for op1 in block.operations: + if (v_func is op1.result and + op1.opname == 'getfield' and + op1.args[0].concretetype == rclass.CLASSTYPE and + op1.args[1].value == 'instantiate'): + x = self.analyze_instantiate_call(seen) + if self.verbose and x: + self.dump_info('analyze_instantiate(%s): %r' % ( + graphs, x)) + return x if self.verbose: self.dump_info('%s to unknown' % (op,)) return self.top_result() @@ -127,7 +143,7 @@ for op in block.operations: result = self.add_to_result( result, - self.analyze(op, seen, graphinfo) + self.analyze(op, seen, graphinfo, block=block) ) if self.is_top_result(result): break @@ -161,7 +177,7 @@ graphs = self.translator.graphs for graph in graphs: for block, op in graph.iterblockops(): - self.analyze(op) + self.analyze(op, block=block) class Dependency(object): diff --git a/rpython/translator/backendopt/test/test_gilanalysis.py b/rpython/translator/backendopt/test/test_gilanalysis.py new file mode 100644 --- /dev/null +++ b/rpython/translator/backendopt/test/test_gilanalysis.py @@ -0,0 +1,80 @@ +import py + +from rpython.annotator.listdef import s_list_of_strings +from rpython.rtyper.lltypesystem import lltype, rffi +from rpython.translator.backendopt import gilanalysis +from rpython.memory.gctransform.test.test_transform import rtype +from rpython.translator.translator import graphof + +def test_canrelease_external(): + for ths in ['auto', True, False]: + for sbxs in [True, False]: + fext = rffi.llexternal('fext2', [], lltype.Void, + threadsafe=ths, sandboxsafe=sbxs) + def g(): + fext() + t = rtype(g, []) + gg = graphof(t, g) + + releases = (ths == 'auto' and not sbxs) or ths is True + assert releases == gilanalysis.GilAnalyzer(t).analyze_direct_call(gg) + +def test_canrelease_instantiate(): + class O: + pass + class A(O): + pass + class B(O): + pass + + classes = [A, B] + def g(i): + classes[i]() + + t = rtype(g, [int]) + gg = graphof(t, g) + assert not gilanalysis.GilAnalyzer(t).analyze_direct_call(gg) + + + +def test_no_release_gil(): + from rpython.rlib import rgc + + @rgc.no_release_gil + def g(): + return 1 + + assert g._dont_inline_ + assert g._no_release_gil_ + + def entrypoint(argv): + return g() + 2 + + t = rtype(entrypoint, [s_list_of_strings]) + gilanalysis.analyze(t.graphs, t) + + + +def test_no_release_gil_detect(gc="minimark"): + from rpython.rlib import rgc + + fext1 = rffi.llexternal('fext1', [], lltype.Void, threadsafe=True) + @rgc.no_release_gil + def g(): + fext1() + return 1 + + assert g._dont_inline_ + assert g._no_release_gil_ + + def entrypoint(argv): + return g() + 2 + + t = rtype(entrypoint, [s_list_of_strings]) + f = py.test.raises(Exception, gilanalysis.analyze, t.graphs, t) + expected = "'no_release_gil' function can release the GIL: Author: Armin Rigo Branch: Changeset: r66817:2c08ebdc17ae Date: 2013-09-05 22:42 +0200 http://bitbucket.org/pypy/pypy/changeset/2c08ebdc17ae/ 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 @@ -77,12 +77,12 @@ raise NotImplementedError("only for interp-level user subclasses " "from typedef.py") - def getname(self, space, default='?'): + def getname(self, space): try: return space.str_w(space.getattr(self, space.wrap('__name__'))) except OperationError, e: if e.match(space, space.w_TypeError) or e.match(space, space.w_AttributeError): - return default + return '?' raise def getaddrstring(self, space): diff --git a/pypy/interpreter/function.py b/pypy/interpreter/function.py --- a/pypy/interpreter/function.py +++ b/pypy/interpreter/function.py @@ -482,17 +482,16 @@ space.abstract_isinstance_w(w_firstarg, self.w_class)): pass # ok else: - clsdescr = self.w_class.getname(space, "") - if clsdescr: + clsdescr = self.w_class.getname(space) + if clsdescr and clsdescr != '?': clsdescr += " instance" else: clsdescr = "instance" if w_firstarg is None: instdescr = "nothing" else: - instname = space.abstract_getclass(w_firstarg).getname(space, - "") - if instname: + instname = space.abstract_getclass(w_firstarg).getname(space) + if instname and instname != '?': instdescr = instname + " instance" else: instdescr = "instance" diff --git a/pypy/interpreter/test/test_argument.py b/pypy/interpreter/test/test_argument.py --- a/pypy/interpreter/test/test_argument.py +++ b/pypy/interpreter/test/test_argument.py @@ -128,7 +128,7 @@ def type(self, obj): class Type: - def getname(self, space, default='?'): + def getname(self, space): return type(obj).__name__ return Type() 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 @@ -175,8 +175,8 @@ state = '; dead' else: typename = space.type(w_obj).getname(space) - objname = w_obj.getname(space, '') - if objname: + objname = w_obj.getname(space) + if objname and objname != '?': state = "; to '%s' (%s)" % (typename, objname) else: state = "; to '%s'" % (typename,) diff --git a/pypy/objspace/descroperation.py b/pypy/objspace/descroperation.py --- a/pypy/objspace/descroperation.py +++ b/pypy/objspace/descroperation.py @@ -597,8 +597,8 @@ if num1 != num2: lt = num1 # if obj1 is a number, it is Lower Than obj2 else: - name1 = w_typ1.getname(space, "") - name2 = w_typ2.getname(space, "") + name1 = w_typ1.getname(space) + name2 = w_typ2.getname(space) if name1 != name2: lt = name1 < name2 else: 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 @@ -494,6 +494,12 @@ else: return w_self.name + def getname(w_self, space): + name = w_self.name + if name is None: + name = '?' + return name + def add_subclass(w_self, w_subclass): space = w_self.space if not space.config.translation.rweakref: 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 @@ -29,6 +29,7 @@ from rpython.rtyper.annlowlevel import llhelper, cast_instance_to_gcref from rpython.rtyper.lltypesystem import lltype, rffi from rpython.jit.backend.arm import callbuilder +from rpython.rtyper.lltypesystem.lloperation import llop class AssemblerARM(ResOpAssembler): @@ -1488,7 +1489,9 @@ def not_implemented(msg): - os.write(2, '[ARM/asm] %s\n' % msg) + msg = '[ARM/asm] %s\n' % msg + if we_are_translated(): + llop.debug_print(lltype.Void, msg) raise NotImplementedError(msg) 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 @@ -2,6 +2,8 @@ from rpython.jit.metainterp.history import Const, Box, REF, JitCellToken from rpython.rlib.objectmodel import we_are_translated, specialize from rpython.jit.metainterp.resoperation import rop +from rpython.rtyper.lltypesystem import lltype +from rpython.rtyper.lltypesystem.lloperation import llop try: from collections import OrderedDict @@ -753,5 +755,7 @@ def not_implemented(msg): - os.write(2, '[llsupport/regalloc] %s\n' % msg) + msg = '[llsupport/regalloc] %s\n' % msg + if we_are_translated(): + llop.debug_print(lltype.Void, msg) raise NotImplementedError(msg) 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 @@ -434,6 +434,7 @@ else: self.wb_slowpath[withcards + 2 * withfloats] = rawstart + @rgc.no_release_gil def assemble_loop(self, logger, loopname, inputargs, operations, looptoken, log): '''adds the following attributes to looptoken: @@ -513,6 +514,7 @@ return AsmInfo(ops_offset, rawstart + looppos, size_excluding_failure_stuff - looppos) + @rgc.no_release_gil def assemble_bridge(self, logger, faildescr, inputargs, operations, original_loop_token, log): if not we_are_translated(): @@ -2388,7 +2390,9 @@ return AddressLoc(ImmedLoc(addr), imm0, 0, 0) def not_implemented(msg): - os.write(2, '[x86/asm] %s\n' % msg) + msg = '[x86/asm] %s\n' % msg + if we_are_translated(): + llop.debug_print(lltype.Void, msg) raise NotImplementedError(msg) cond_call_register_arguments = [edi, esi, edx, ecx] 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 @@ -28,6 +28,7 @@ from rpython.rlib.rarithmetic import r_longlong, r_uint from rpython.rtyper.annlowlevel import cast_instance_to_gcref from rpython.rtyper.lltypesystem import lltype, rffi, rstr +from rpython.rtyper.lltypesystem.lloperation import llop class X86RegisterManager(RegisterManager): @@ -1375,7 +1376,9 @@ return base_ofs + WORD * (position + JITFRAME_FIXED_SIZE) def not_implemented(msg): - os.write(2, '[x86/regalloc] %s\n' % msg) + msg = '[x86/regalloc] %s\n' % msg + if we_are_translated(): + llop.debug_print(lltype.Void, msg) raise NotImplementedError(msg) # xxx hack: set a default value for TargetToken._ll_loop_code. 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 @@ -1,6 +1,7 @@ import py from rpython.rtyper.lltypesystem import lltype, llmemory, rffi from rpython.rlib.jit_hooks import LOOP_RUN_CONTAINER +from rpython.rlib import rgc from rpython.jit.backend.x86.assembler import Assembler386 from rpython.jit.backend.x86.regalloc import gpr_reg_mgr_cls, xmm_reg_mgr_cls from rpython.jit.backend.x86.profagent import ProfileAgent @@ -63,10 +64,12 @@ assert self.assembler is not None return RegAlloc(self.assembler, False) + @rgc.no_release_gil def setup_once(self): self.profile_agent.startup() self.assembler.setup_once() + @rgc.no_release_gil def finish_once(self): self.assembler.finish_once() self.profile_agent.shutdown() diff --git a/rpython/rlib/rgc.py b/rpython/rlib/rgc.py --- a/rpython/rlib/rgc.py +++ b/rpython/rlib/rgc.py @@ -262,7 +262,11 @@ keepalive_until_here(newp) return newp - +def no_release_gil(func): + func._dont_inline_ = True + func._no_release_gil_ = True + return func + def no_collect(func): func._dont_inline_ = True func._gc_no_collect_ = True diff --git a/rpython/translator/backendopt/all.py b/rpython/translator/backendopt/all.py --- a/rpython/translator/backendopt/all.py +++ b/rpython/translator/backendopt/all.py @@ -10,6 +10,7 @@ from rpython.translator.backendopt.removeassert import remove_asserts from rpython.translator.backendopt.support import log from rpython.translator.backendopt.storesink import storesink_graph +from rpython.translator.backendopt import gilanalysis from rpython.flowspace.model import checkgraph INLINE_THRESHOLD_FOR_TEST = 33 @@ -138,6 +139,9 @@ for graph in graphs: checkgraph(graph) + gilanalysis.analyze(graphs, translator) + + def constfold(config, graphs): if config.constfold: for graph in graphs: diff --git a/rpython/translator/backendopt/gilanalysis.py b/rpython/translator/backendopt/gilanalysis.py new file mode 100644 --- /dev/null +++ b/rpython/translator/backendopt/gilanalysis.py @@ -0,0 +1,60 @@ +from rpython.translator.backendopt import graphanalyze + +# This is not an optimization. It checks for possible releases of the +# GIL in all graphs starting from rgc.no_release_gil. + + +class GilAnalyzer(graphanalyze.BoolGraphAnalyzer): + + def analyze_direct_call(self, graph, seen=None): + try: + func = graph.func + except AttributeError: + pass + else: + if getattr(func, '_gctransformer_hint_close_stack_', False): + return True + if getattr(func, '_transaction_break_', False): + return True + + return graphanalyze.BoolGraphAnalyzer.analyze_direct_call( + self, graph, seen) + + def analyze_external_call(self, op, seen=None): + funcobj = op.args[0].value._obj + if getattr(funcobj, 'transactionsafe', False): + return False + else: + return False + + def analyze_instantiate_call(self, seen=None): + return False + + def analyze_simple_operation(self, op, graphinfo): + return False + +def analyze(graphs, translator): + gilanalyzer = GilAnalyzer(translator) + for graph in graphs: + func = getattr(graph, 'func', None) + if func and getattr(func, '_no_release_gil_', False): + if gilanalyzer.analyze_direct_call(graph): + # 'no_release_gil' function can release the gil + import cStringIO + err = cStringIO.StringIO() + import sys + prev = sys.stdout + try: + sys.stdout = err + ca = GilAnalyzer(translator) + ca.verbose = True + ca.analyze_direct_call(graph) # print the "traceback" here + sys.stdout = prev + except: + sys.stdout = prev + # ^^^ for the dump of which operation in which graph actually + # causes it to return True + raise Exception("'no_release_gil' function can release the GIL:" + " %s\n%s" % (func, err.getvalue())) + + diff --git a/rpython/translator/backendopt/graphanalyze.py b/rpython/translator/backendopt/graphanalyze.py --- a/rpython/translator/backendopt/graphanalyze.py +++ b/rpython/translator/backendopt/graphanalyze.py @@ -1,6 +1,7 @@ from rpython.rtyper.lltypesystem.lltype import DelayedPointer from rpython.translator.simplify import get_graph from rpython.tool.algo.unionfind import UnionFind +from rpython.rtyper.lltypesystem import rclass class GraphAnalyzer(object): @@ -67,6 +68,9 @@ result, self.analyze_direct_call(graph, seen)) return result + def analyze_instantiate_call(self, seen=None): + return self.top_result() + def analyze_link(self, graph, link): return self.bottom_result() @@ -75,7 +79,7 @@ def compute_graph_info(self, graph): return None - def analyze(self, op, seen=None, graphinfo=None): + def analyze(self, op, seen=None, graphinfo=None, block=None): if op.opname == "direct_call": graph = get_graph(op.args[0], self.translator) if graph is None: @@ -90,6 +94,18 @@ elif op.opname == "indirect_call": graphs = op.args[-1].value if graphs is None: + if block is not None: + v_func = op.args[0] + for op1 in block.operations: + if (v_func is op1.result and + op1.opname == 'getfield' and + op1.args[0].concretetype == rclass.CLASSTYPE and + op1.args[1].value == 'instantiate'): + x = self.analyze_instantiate_call(seen) + if self.verbose and x: + self.dump_info('analyze_instantiate(%s): %r' % ( + graphs, x)) + return x if self.verbose: self.dump_info('%s to unknown' % (op,)) return self.top_result() @@ -127,7 +143,7 @@ for op in block.operations: result = self.add_to_result( result, - self.analyze(op, seen, graphinfo) + self.analyze(op, seen, graphinfo, block=block) ) if self.is_top_result(result): break @@ -161,7 +177,7 @@ graphs = self.translator.graphs for graph in graphs: for block, op in graph.iterblockops(): - self.analyze(op) + self.analyze(op, block=block) class Dependency(object): diff --git a/rpython/translator/backendopt/test/test_gilanalysis.py b/rpython/translator/backendopt/test/test_gilanalysis.py new file mode 100644 --- /dev/null +++ b/rpython/translator/backendopt/test/test_gilanalysis.py @@ -0,0 +1,80 @@ +import py + +from rpython.annotator.listdef import s_list_of_strings +from rpython.rtyper.lltypesystem import lltype, rffi +from rpython.translator.backendopt import gilanalysis +from rpython.memory.gctransform.test.test_transform import rtype +from rpython.translator.translator import graphof + +def test_canrelease_external(): + for ths in ['auto', True, False]: + for sbxs in [True, False]: + fext = rffi.llexternal('fext2', [], lltype.Void, + threadsafe=ths, sandboxsafe=sbxs) + def g(): + fext() + t = rtype(g, []) + gg = graphof(t, g) + + releases = (ths == 'auto' and not sbxs) or ths is True + assert releases == gilanalysis.GilAnalyzer(t).analyze_direct_call(gg) + +def test_canrelease_instantiate(): + class O: + pass + class A(O): + pass + class B(O): + pass + + classes = [A, B] + def g(i): + classes[i]() + + t = rtype(g, [int]) + gg = graphof(t, g) + assert not gilanalysis.GilAnalyzer(t).analyze_direct_call(gg) + + + +def test_no_release_gil(): + from rpython.rlib import rgc + + @rgc.no_release_gil + def g(): + return 1 + + assert g._dont_inline_ + assert g._no_release_gil_ + + def entrypoint(argv): + return g() + 2 + + t = rtype(entrypoint, [s_list_of_strings]) + gilanalysis.analyze(t.graphs, t) + + + +def test_no_release_gil_detect(gc="minimark"): + from rpython.rlib import rgc + + fext1 = rffi.llexternal('fext1', [], lltype.Void, threadsafe=True) + @rgc.no_release_gil + def g(): + fext1() + return 1 + + assert g._dont_inline_ + assert g._no_release_gil_ + + def entrypoint(argv): + return g() + 2 + + t = rtype(entrypoint, [s_list_of_strings]) + f = py.test.raises(Exception, gilanalysis.analyze, t.graphs, t) + expected = "'no_release_gil' function can release the GIL: Author: Remi Meier Branch: stmgc-c4 Changeset: r66818:f7c74429d527 Date: 2013-09-06 11:11 +0200 http://bitbucket.org/pypy/pypy/changeset/f7c74429d527/ Log: more jit.dont_look_inside needed after merge diff --git a/pypy/module/__pypy__/interp_signal.py b/pypy/module/__pypy__/interp_signal.py --- a/pypy/module/__pypy__/interp_signal.py +++ b/pypy/module/__pypy__/interp_signal.py @@ -1,6 +1,9 @@ +from rpython.rlib import jit + at jit.dont_look_inside def signals_enter(space): space.threadlocals.enable_signals(space) + at jit.dont_look_inside def signals_exit(space, w_ignored1=None, w_ignored2=None, w_ignored3=None): space.threadlocals.disable_signals(space) diff --git a/pypy/module/thread/stm.py b/pypy/module/thread/stm.py --- a/pypy/module/thread/stm.py +++ b/pypy/module/thread/stm.py @@ -28,6 +28,7 @@ if not we_are_translated() and not hasattr(ec, '_thread_local_dicts'): initialize_execution_context(ec) + at jit.dont_look_inside # XXX: handle abort_info_push in JIT def enter_frame(ec, frame): """Called from ExecutionContext.enter().""" if frame.hide(): diff --git a/rpython/rlib/rstm.py b/rpython/rlib/rstm.py --- a/rpython/rlib/rstm.py +++ b/rpython/rlib/rstm.py @@ -58,7 +58,6 @@ def is_atomic(): return llop.stm_get_atomic(lltype.Signed) - at dont_look_inside def abort_info_push(instance, fieldnames): "Special-cased below." From noreply at buildbot.pypy.org Fri Sep 6 15:35:06 2013 From: noreply at buildbot.pypy.org (arigo) Date: Fri, 6 Sep 2013 15:35:06 +0200 (CEST) Subject: [pypy-commit] pypy default: Add a passing test for the usage case in Message-ID: <20130906133506.13F341C0315@cobra.cs.uni-duesseldorf.de> Author: Armin Rigo Branch: Changeset: r66819:136ece4043c9 Date: 2013-09-06 15:34 +0200 http://bitbucket.org/pypy/pypy/changeset/136ece4043c9/ Log: Add a passing test for the usage case in pypy/module/_cffi_backend/newtype:new_primitive_type() diff --git a/rpython/rtyper/test/test_rclass.py b/rpython/rtyper/test/test_rclass.py --- a/rpython/rtyper/test/test_rclass.py +++ b/rpython/rtyper/test/test_rclass.py @@ -1192,3 +1192,19 @@ assert self.interpret(f, [True]) == f(True) assert self.interpret(f, [False]) == f(False) + + def test_init_with_star_args(self): + class Base(object): + def __init__(self, a, b): + self.a = a + self.b = b + class A(Base): + def __init__(self, *args): + Base.__init__(self, *args) + self.c = -1 + cls = [Base, A] + + def f(k, a, b): + return cls[k](a, b).b + + assert self.interpret(f, [1, 4, 7]) == 7 From noreply at buildbot.pypy.org Fri Sep 6 19:36:38 2013 From: noreply at buildbot.pypy.org (arigo) Date: Fri, 6 Sep 2013 19:36:38 +0200 (CEST) Subject: [pypy-commit] pypy default: issue1596: support for OpenSuSE 12.2. (thanks Skip) Message-ID: <20130906173638.2F1F01C0370@cobra.cs.uni-duesseldorf.de> Author: Armin Rigo Branch: Changeset: r66820:8dc8224d017a Date: 2013-09-06 19:35 +0200 http://bitbucket.org/pypy/pypy/changeset/8dc8224d017a/ Log: issue1596: support for OpenSuSE 12.2. (thanks Skip) 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 @@ -26,6 +26,9 @@ def try_ldflags(): yield ExternalCompilationInfo(libraries=['curses']) yield ExternalCompilationInfo(libraries=['curses', 'tinfo']) + yield ExternalCompilationInfo(libraries=['ncurses']) + yield ExternalCompilationInfo(libraries=['ncurses'], + library_dirs=['/usr/lib64']) def try_tools(): try: From noreply at buildbot.pypy.org Fri Sep 6 19:50:24 2013 From: noreply at buildbot.pypy.org (arigo) Date: Fri, 6 Sep 2013 19:50:24 +0200 (CEST) Subject: [pypy-commit] stmgc default: Another test that the pushed abort_info objects are kept alive Message-ID: <20130906175024.DF1621C0370@cobra.cs.uni-duesseldorf.de> Author: Armin Rigo Branch: Changeset: r520:f474f2b3bee9 Date: 2013-09-06 19:50 +0200 http://bitbucket.org/pypy/stmgc/changeset/f474f2b3bee9/ Log: Another test that the pushed abort_info objects are kept alive diff --git a/c4/test/test_extra.py b/c4/test/test_extra.py --- a/c4/test/test_extra.py +++ b/c4/test/test_extra.py @@ -56,21 +56,31 @@ def test_inspect_abort_info_string(): fo1 = ffi.new("long[]", [3, HDR + WORD, HDR, 0]) # - @perform_transaction def run(retry_counter): if retry_counter == 0: p = nalloc_refs(2) + lib.stm_push_root(p) q = nalloc(HDR + 2 * WORD) + p = lib.stm_pop_root() lib.setptr(p, 1, q) lib.setlong(q, 0, 3) word = "ABC" + "\xFF" * (WORD - 3) lib.setlong(q, 1, struct.unpack("l", word)[0]) lib.stm_abort_info_push(p, fo1) + possibly_collect() abort_and_retry() else: + possibly_collect() c = lib.stm_inspect_abort_info() assert c assert ffi.string(c).endswith("e3:ABCe") + # + def no_collect(): + pass + for possibly_collect in [no_collect, minor_collect, major_collect]: + print '-'*79 + print 'running with', possibly_collect + perform_transaction(run) def test_inspect_null(): fo1 = ffi.new("long[]", [3, HDR, HDR + 1, 0]) From noreply at buildbot.pypy.org Fri Sep 6 21:14:58 2013 From: noreply at buildbot.pypy.org (arigo) Date: Fri, 6 Sep 2013 21:14:58 +0200 (CEST) Subject: [pypy-commit] stmgc default: Even more complications in the decoding of abort info: Message-ID: <20130906191458.2C57B1C02CD@cobra.cs.uni-duesseldorf.de> Author: Armin Rigo Branch: Changeset: r521:24b6be3aaa67 Date: 2013-09-06 21:12 +0200 http://bitbucket.org/pypy/stmgc/changeset/24b6be3aaa67/ Log: Even more complications in the decoding of abort info: move the (missing-so-far) stm_read_barrier() later, during the call to stm_inspect_abort_info(). diff --git a/c4/et.c b/c4/et.c --- a/c4/et.c +++ b/c4/et.c @@ -24,7 +24,7 @@ } cur += sprintf(cur, "tid=%ld", stm_get_tid(obj)); cur += sprintf(cur, " : rev=%lx : orig=%lx", - obj->h_revision, obj->h_original); + (long)obj->h_revision, (long)obj->h_original); return tmp_buf; } @@ -950,8 +950,8 @@ d->longest_abort_info_time = 0; /* out of memory! */ else { - if (stm_decode_abort_info(d, elapsed_time, - num, d->longest_abort_info) != size) + if (stm_decode_abort_info(d, elapsed_time, num, + (struct tx_abort_info *)d->longest_abort_info) != size) stm_fatalerror("during stm abort: object mutated unexpectedly\n"); d->longest_abort_info_time = elapsed_time; diff --git a/c4/extra.c b/c4/extra.c --- a/c4/extra.c +++ b/c4/extra.c @@ -235,13 +235,75 @@ } size_t stm_decode_abort_info(struct tx_descriptor *d, long long elapsed_time, - int abort_reason, char *output) + int abort_reason, struct tx_abort_info *output) { - /* re-encodes the abort info as a single string. + /* Re-encodes the abort info as a single tx_abort_info structure. + This struct tx_abort_info is not visible to the outside, and used + only as an intermediate format that is fast to generate and without + requiring stm_read_barrier(). + */ + if (output != NULL) { + output->signature_packed = 127; + output->elapsed_time = elapsed_time; + output->abort_reason = abort_reason; + output->active = d->active; + output->atomic = d->atomic; + output->count_reads = d->count_reads; + output->reads_size_limit_nonatomic = d->reads_size_limit_nonatomic; + } + + long num_words = 0; +#define WRITE_WORD(word) { \ + if (output) output->words[num_words] = (word); \ + num_words++; \ + } + + long i; + for (i=0; iabortinfo.size; i+=2) { + char *object = (char*)stm_repeat_read_barrier(d->abortinfo.items[i+0]); + long *fieldoffsets = (long*)d->abortinfo.items[i+1]; + long kind, offset; + while (*fieldoffsets != 0) { + kind = *fieldoffsets++; + WRITE_WORD(kind); + if (kind < 0) { + /* -1 is start of sublist; -2 is end of sublist */ + continue; + } + offset = *fieldoffsets++; + switch(kind) { + case 1: /* signed */ + case 2: /* unsigned */ + WRITE_WORD(*(long *)(object + offset)); + break; + case 3: /* a string of bytes from the target object */ + WRITE_WORD((revision_t)*(char **)(object + offset)); + offset = *fieldoffsets++; /* offset of len in the string */ + WRITE_WORD(offset); + break; + default: + stm_fatalerror("corrupted abort log\n"); + } + } + } + WRITE_WORD(0); +#undef WRITE_WORD + return sizeof(struct tx_abort_info) + (num_words - 1) * sizeof(revision_t); +} + +static size_t unpack_abort_info(struct tx_descriptor *d, + struct tx_abort_info *ai, + char *output) +{ + /* Lazily decodes a struct tx_abort_info into a single plain string. For convenience (no escaping needed, no limit on integer - sizes, etc.) we follow the bittorrent format. */ + sizes, etc.) we follow the bittorrent format. This makes the + format a bit more flexible for future changes. The struct + tx_abort_info is still needed as an intermediate step, because + the string parameters may not be readable during an abort + (they may be stubs). + */ size_t totalsize = 0; - long i; char buffer[32]; size_t res_size; #define WRITE(c) { totalsize++; if (output) *output++=(c); } @@ -252,75 +314,74 @@ } WRITE('l'); WRITE('l'); - res_size = sprintf(buffer, "i%llde", (long long)elapsed_time); + res_size = sprintf(buffer, "i%llde", (long long)ai->elapsed_time); WRITE_BUF(buffer, res_size); - res_size = sprintf(buffer, "i%de", (int)abort_reason); + res_size = sprintf(buffer, "i%de", (int)ai->abort_reason); WRITE_BUF(buffer, res_size); res_size = sprintf(buffer, "i%lde", (long)d->public_descriptor_index); WRITE_BUF(buffer, res_size); - res_size = sprintf(buffer, "i%lde", (long)d->atomic); + res_size = sprintf(buffer, "i%lde", (long)ai->atomic); WRITE_BUF(buffer, res_size); - res_size = sprintf(buffer, "i%de", (int)d->active); + res_size = sprintf(buffer, "i%de", (int)ai->active); WRITE_BUF(buffer, res_size); - res_size = sprintf(buffer, "i%lue", (unsigned long)d->count_reads); + res_size = sprintf(buffer, "i%lue", (unsigned long)ai->count_reads); WRITE_BUF(buffer, res_size); res_size = sprintf(buffer, "i%lue", - (unsigned long)d->reads_size_limit_nonatomic); + (unsigned long)ai->reads_size_limit_nonatomic); WRITE_BUF(buffer, res_size); WRITE('e'); - for (i=0; iabortinfo.size; i+=2) { - char *object = (char*)stm_repeat_read_barrier(d->abortinfo.items[i+0]); - long *fieldoffsets = (long*)d->abortinfo.items[i+1]; - long kind, offset; - size_t rps_size; + + revision_t *src = ai->words; + while (*src != 0) { + long signed_value; + unsigned long unsigned_value; char *rps; + long offset, rps_size; - while (1) { - kind = *fieldoffsets++; - if (kind <= 0) { - if (kind == -2) { - WRITE('l'); /* '[', start of sublist */ - continue; - } - if (kind == -1) { - WRITE('e'); /* ']', end of sublist */ - continue; - } - break; /* 0, terminator */ + switch (*src++) { + + case -2: + WRITE('l'); /* '[', start of sublist */ + break; + + case -1: + WRITE('e'); /* ']', end of sublist */ + break; + + case 1: /* signed */ + signed_value = (long)(*src++); + res_size = sprintf(buffer, "i%lde", signed_value); + WRITE_BUF(buffer, res_size); + break; + + case 2: /* unsigned */ + unsigned_value = (unsigned long)(*src++); + res_size = sprintf(buffer, "i%lue", unsigned_value); + WRITE_BUF(buffer, res_size); + break; + + case 3: /* a string of bytes from the target object */ + rps = (char *)(*src++); + offset = *src++; + if (rps) { + rps = (char *)stm_read_barrier((gcptr)rps); + /* xxx a bit ad-hoc: it's a string whose length is a + * long at 'rps_size'; the string data follows + * immediately the length */ + rps_size = *(long *)(rps + offset); + assert(rps_size >= 0); + res_size = sprintf(buffer, "%ld:", rps_size); + WRITE_BUF(buffer, res_size); + WRITE_BUF(rps + offset + sizeof(long), rps_size); } - offset = *fieldoffsets++; - switch(kind) { - case 1: /* signed */ - res_size = sprintf(buffer, "i%lde", - *(long*)(object + offset)); - WRITE_BUF(buffer, res_size); - break; - case 2: /* unsigned */ - res_size = sprintf(buffer, "i%lue", - *(unsigned long*)(object + offset)); - WRITE_BUF(buffer, res_size); - break; - case 3: /* a string of bytes from the target object */ - rps = *(char **)(object + offset); - offset = *fieldoffsets++; - /* XXX think of a different hack: this one doesn't really - work if we see stubs! */ - if (rps && !(((gcptr)rps)->h_tid & GCFLAG_STUB)) { - /* xxx a bit ad-hoc: it's a string whose length is a - * long at 'offset', following immediately the offset */ - rps_size = *(long *)(rps + offset); - assert(rps_size >= 0); - res_size = sprintf(buffer, "%zu:", rps_size); - WRITE_BUF(buffer, res_size); - WRITE_BUF(rps + offset + sizeof(long), rps_size); - } - else { - WRITE_BUF("0:", 2); - } - break; - default: - stm_fatalerror("corrupted abort log\n"); + else { + /* write NULL as an empty string, good enough for now */ + WRITE_BUF("0:", 2); } + break; + + default: + stm_fatalerror("corrupted abort log\n"); } } WRITE('e'); @@ -335,6 +396,53 @@ struct tx_descriptor *d = thread_descriptor; if (d->longest_abort_info_time <= 0) return NULL; + + struct tx_abort_info *ai = (struct tx_abort_info *)d->longest_abort_info; + assert(ai->signature_packed == 127); + + stm_become_inevitable("stm_inspect_abort_info"); + + size_t size = unpack_abort_info(d, ai, NULL); + char *text = malloc(size); + if (text == NULL) + return NULL; /* out of memory */ + if (unpack_abort_info(d, ai, text) != size) + stm_fatalerror("stm_inspect_abort_info: " + "object mutated unexpectedly\n"); + free(ai); + d->longest_abort_info = text; d->longest_abort_info_time = 0; return d->longest_abort_info; } + +void stm_visit_abort_info(struct tx_descriptor *d, void (*visit)(gcptr *)) +{ + long i, size = d->abortinfo.size; + gcptr *items = d->abortinfo.items; + for (i = 0; i < size; i += 2) { + visit(&items[i]); + /* items[i+1] is not a gc ptr */ + } + + struct tx_abort_info *ai = (struct tx_abort_info *)d->longest_abort_info; + if (ai != NULL && ai->signature_packed == 127) { + revision_t *src = ai->words; + while (*src != 0) { + gcptr *rpps; + + switch (*src++) { + + case 1: /* signed */ + case 2: /* unsigned */ + src++; /* ignore the value */ + break; + + case 3: + rpps = (gcptr *)(src++); + src++; /* ignore the offset */ + visit(rpps); /* visit() the string object */ + break; + } + } + } +} diff --git a/c4/extra.h b/c4/extra.h --- a/c4/extra.h +++ b/c4/extra.h @@ -2,8 +2,20 @@ #define _SRCSTM_EXTRA_H +struct tx_abort_info { + char signature_packed; /* 127 when the abort_info is in this format */ + long long elapsed_time; + int abort_reason; + int active; + long atomic; + unsigned long count_reads; + unsigned long reads_size_limit_nonatomic; + revision_t words[1]; /* the 'words' list is a bytecode-like format */ +}; + void stm_copy_to_old_id_copy(gcptr obj, gcptr id); size_t stm_decode_abort_info(struct tx_descriptor *d, long long elapsed_time, - int abort_reason, char *output); + int abort_reason, struct tx_abort_info *output); +void stm_visit_abort_info(struct tx_descriptor *d, void (*visit)(gcptr *)); #endif diff --git a/c4/gcpage.c b/c4/gcpage.c --- a/c4/gcpage.c +++ b/c4/gcpage.c @@ -562,12 +562,7 @@ visit_take_protected(&d->old_thread_local_obj); /* the abortinfo objects */ - long i, size = d->abortinfo.size; - gcptr *items = d->abortinfo.items; - for (i = 0; i < size; i += 2) { - visit_take_protected(&items[i]); - /* items[i+1] is not a gc ptr */ - } + stm_visit_abort_info(d, &visit_take_protected); /* the current transaction's private copies of public objects */ wlog_t *item; @@ -600,8 +595,8 @@ } G2L_LOOP_END; /* reinsert to real pub_to_priv */ - size = new_public_to_private.size; - items = new_public_to_private.items; + long i, size = new_public_to_private.size; + gcptr *items = new_public_to_private.items; for (i = 0; i < size; i += 2) { g2l_insert(&d->public_to_private, items[i], items[i + 1]); } diff --git a/c4/nursery.c b/c4/nursery.c --- a/c4/nursery.c +++ b/c4/nursery.c @@ -455,12 +455,7 @@ visit_if_young(d->thread_local_obj_ref); visit_if_young(&d->old_thread_local_obj); - long i, size = d->abortinfo.size; - gcptr *items = d->abortinfo.items; - for (i = 0; i < size; i += 2) { - visit_if_young(&items[i]); - /* items[i+1] is not a gc ptr */ - } + stm_visit_abort_info(d, &visit_if_young); } static void minor_collect(struct tx_descriptor *d) diff --git a/c4/stmgc.h b/c4/stmgc.h --- a/c4/stmgc.h +++ b/c4/stmgc.h @@ -154,7 +154,7 @@ stm_inspect_abort_info(). (XXX details not documented yet) */ void stm_abort_info_push(gcptr obj, long fieldoffsets[]); void stm_abort_info_pop(long count); -char *stm_inspect_abort_info(void); +char *stm_inspect_abort_info(void); /* turns inevitable */ /* mostly for debugging support */ void stm_abort_and_retry(void); diff --git a/c4/test/test_extra.py b/c4/test/test_extra.py --- a/c4/test/test_extra.py +++ b/c4/test/test_extra.py @@ -19,6 +19,8 @@ # no real test here def test_inspect_abort_info_signed(): + c = lib.stm_inspect_abort_info() + assert not c fo1 = ffi.new("long[]", [-2, 1, HDR, -1, 0]) # @perform_transaction @@ -32,6 +34,8 @@ c = lib.stm_inspect_abort_info() assert c assert ffi.string(c).endswith("eli-421289712eee") + c = lib.stm_inspect_abort_info() + assert not c def test_inspect_abort_info_nested_unsigned(): fo1 = ffi.new("long[]", [-2, 2, HDR, 0]) From noreply at buildbot.pypy.org Fri Sep 6 21:24:12 2013 From: noreply at buildbot.pypy.org (arigo) Date: Fri, 6 Sep 2013 21:24:12 +0200 (CEST) Subject: [pypy-commit] pypy stmgc-c4: Import stmgc/24b6be3aaa67 Message-ID: <20130906192412.E27C91C02CD@cobra.cs.uni-duesseldorf.de> Author: Armin Rigo Branch: stmgc-c4 Changeset: r66821:39d7738e08f8 Date: 2013-09-06 21:23 +0200 http://bitbucket.org/pypy/pypy/changeset/39d7738e08f8/ Log: Import stmgc/24b6be3aaa67 diff --git a/rpython/translator/stm/src_stm/et.c b/rpython/translator/stm/src_stm/et.c --- a/rpython/translator/stm/src_stm/et.c +++ b/rpython/translator/stm/src_stm/et.c @@ -25,7 +25,7 @@ } cur += sprintf(cur, "tid=%ld", stm_get_tid(obj)); cur += sprintf(cur, " : rev=%lx : orig=%lx", - obj->h_revision, obj->h_original); + (long)obj->h_revision, (long)obj->h_original); return tmp_buf; } @@ -951,8 +951,8 @@ d->longest_abort_info_time = 0; /* out of memory! */ else { - if (stm_decode_abort_info(d, elapsed_time, - num, d->longest_abort_info) != size) + if (stm_decode_abort_info(d, elapsed_time, num, + (struct tx_abort_info *)d->longest_abort_info) != size) stm_fatalerror("during stm abort: object mutated unexpectedly\n"); d->longest_abort_info_time = elapsed_time; diff --git a/rpython/translator/stm/src_stm/extra.c b/rpython/translator/stm/src_stm/extra.c --- a/rpython/translator/stm/src_stm/extra.c +++ b/rpython/translator/stm/src_stm/extra.c @@ -236,13 +236,75 @@ } size_t stm_decode_abort_info(struct tx_descriptor *d, long long elapsed_time, - int abort_reason, char *output) + int abort_reason, struct tx_abort_info *output) { - /* re-encodes the abort info as a single string. + /* Re-encodes the abort info as a single tx_abort_info structure. + This struct tx_abort_info is not visible to the outside, and used + only as an intermediate format that is fast to generate and without + requiring stm_read_barrier(). + */ + if (output != NULL) { + output->signature_packed = 127; + output->elapsed_time = elapsed_time; + output->abort_reason = abort_reason; + output->active = d->active; + output->atomic = d->atomic; + output->count_reads = d->count_reads; + output->reads_size_limit_nonatomic = d->reads_size_limit_nonatomic; + } + + long num_words = 0; +#define WRITE_WORD(word) { \ + if (output) output->words[num_words] = (word); \ + num_words++; \ + } + + long i; + for (i=0; iabortinfo.size; i+=2) { + char *object = (char*)stm_repeat_read_barrier(d->abortinfo.items[i+0]); + long *fieldoffsets = (long*)d->abortinfo.items[i+1]; + long kind, offset; + while (*fieldoffsets != 0) { + kind = *fieldoffsets++; + WRITE_WORD(kind); + if (kind < 0) { + /* -1 is start of sublist; -2 is end of sublist */ + continue; + } + offset = *fieldoffsets++; + switch(kind) { + case 1: /* signed */ + case 2: /* unsigned */ + WRITE_WORD(*(long *)(object + offset)); + break; + case 3: /* a string of bytes from the target object */ + WRITE_WORD((revision_t)*(char **)(object + offset)); + offset = *fieldoffsets++; /* offset of len in the string */ + WRITE_WORD(offset); + break; + default: + stm_fatalerror("corrupted abort log\n"); + } + } + } + WRITE_WORD(0); +#undef WRITE_WORD + return sizeof(struct tx_abort_info) + (num_words - 1) * sizeof(revision_t); +} + +static size_t unpack_abort_info(struct tx_descriptor *d, + struct tx_abort_info *ai, + char *output) +{ + /* Lazily decodes a struct tx_abort_info into a single plain string. For convenience (no escaping needed, no limit on integer - sizes, etc.) we follow the bittorrent format. */ + sizes, etc.) we follow the bittorrent format. This makes the + format a bit more flexible for future changes. The struct + tx_abort_info is still needed as an intermediate step, because + the string parameters may not be readable during an abort + (they may be stubs). + */ size_t totalsize = 0; - long i; char buffer[32]; size_t res_size; #define WRITE(c) { totalsize++; if (output) *output++=(c); } @@ -253,75 +315,74 @@ } WRITE('l'); WRITE('l'); - res_size = sprintf(buffer, "i%llde", (long long)elapsed_time); + res_size = sprintf(buffer, "i%llde", (long long)ai->elapsed_time); WRITE_BUF(buffer, res_size); - res_size = sprintf(buffer, "i%de", (int)abort_reason); + res_size = sprintf(buffer, "i%de", (int)ai->abort_reason); WRITE_BUF(buffer, res_size); res_size = sprintf(buffer, "i%lde", (long)d->public_descriptor_index); WRITE_BUF(buffer, res_size); - res_size = sprintf(buffer, "i%lde", (long)d->atomic); + res_size = sprintf(buffer, "i%lde", (long)ai->atomic); WRITE_BUF(buffer, res_size); - res_size = sprintf(buffer, "i%de", (int)d->active); + res_size = sprintf(buffer, "i%de", (int)ai->active); WRITE_BUF(buffer, res_size); - res_size = sprintf(buffer, "i%lue", (unsigned long)d->count_reads); + res_size = sprintf(buffer, "i%lue", (unsigned long)ai->count_reads); WRITE_BUF(buffer, res_size); res_size = sprintf(buffer, "i%lue", - (unsigned long)d->reads_size_limit_nonatomic); + (unsigned long)ai->reads_size_limit_nonatomic); WRITE_BUF(buffer, res_size); WRITE('e'); - for (i=0; iabortinfo.size; i+=2) { - char *object = (char*)stm_repeat_read_barrier(d->abortinfo.items[i+0]); - long *fieldoffsets = (long*)d->abortinfo.items[i+1]; - long kind, offset; - size_t rps_size; + + revision_t *src = ai->words; + while (*src != 0) { + long signed_value; + unsigned long unsigned_value; char *rps; + long offset, rps_size; - while (1) { - kind = *fieldoffsets++; - if (kind <= 0) { - if (kind == -2) { - WRITE('l'); /* '[', start of sublist */ - continue; - } - if (kind == -1) { - WRITE('e'); /* ']', end of sublist */ - continue; - } - break; /* 0, terminator */ + switch (*src++) { + + case -2: + WRITE('l'); /* '[', start of sublist */ + break; + + case -1: + WRITE('e'); /* ']', end of sublist */ + break; + + case 1: /* signed */ + signed_value = (long)(*src++); + res_size = sprintf(buffer, "i%lde", signed_value); + WRITE_BUF(buffer, res_size); + break; + + case 2: /* unsigned */ + unsigned_value = (unsigned long)(*src++); + res_size = sprintf(buffer, "i%lue", unsigned_value); + WRITE_BUF(buffer, res_size); + break; + + case 3: /* a string of bytes from the target object */ + rps = (char *)(*src++); + offset = *src++; + if (rps) { + rps = (char *)stm_read_barrier((gcptr)rps); + /* xxx a bit ad-hoc: it's a string whose length is a + * long at 'rps_size'; the string data follows + * immediately the length */ + rps_size = *(long *)(rps + offset); + assert(rps_size >= 0); + res_size = sprintf(buffer, "%ld:", rps_size); + WRITE_BUF(buffer, res_size); + WRITE_BUF(rps + offset + sizeof(long), rps_size); } - offset = *fieldoffsets++; - switch(kind) { - case 1: /* signed */ - res_size = sprintf(buffer, "i%lde", - *(long*)(object + offset)); - WRITE_BUF(buffer, res_size); - break; - case 2: /* unsigned */ - res_size = sprintf(buffer, "i%lue", - *(unsigned long*)(object + offset)); - WRITE_BUF(buffer, res_size); - break; - case 3: /* a string of bytes from the target object */ - rps = *(char **)(object + offset); - offset = *fieldoffsets++; - /* XXX think of a different hack: this one doesn't really - work if we see stubs! */ - if (rps && !(((gcptr)rps)->h_tid & GCFLAG_STUB)) { - /* xxx a bit ad-hoc: it's a string whose length is a - * long at 'offset', following immediately the offset */ - rps_size = *(long *)(rps + offset); - assert(rps_size >= 0); - res_size = sprintf(buffer, "%zu:", rps_size); - WRITE_BUF(buffer, res_size); - WRITE_BUF(rps + offset + sizeof(long), rps_size); - } - else { - WRITE_BUF("0:", 2); - } - break; - default: - stm_fatalerror("corrupted abort log\n"); + else { + /* write NULL as an empty string, good enough for now */ + WRITE_BUF("0:", 2); } + break; + + default: + stm_fatalerror("corrupted abort log\n"); } } WRITE('e'); @@ -336,6 +397,53 @@ struct tx_descriptor *d = thread_descriptor; if (d->longest_abort_info_time <= 0) return NULL; + + struct tx_abort_info *ai = (struct tx_abort_info *)d->longest_abort_info; + assert(ai->signature_packed == 127); + + stm_become_inevitable("stm_inspect_abort_info"); + + size_t size = unpack_abort_info(d, ai, NULL); + char *text = malloc(size); + if (text == NULL) + return NULL; /* out of memory */ + if (unpack_abort_info(d, ai, text) != size) + stm_fatalerror("stm_inspect_abort_info: " + "object mutated unexpectedly\n"); + free(ai); + d->longest_abort_info = text; d->longest_abort_info_time = 0; return d->longest_abort_info; } + +void stm_visit_abort_info(struct tx_descriptor *d, void (*visit)(gcptr *)) +{ + long i, size = d->abortinfo.size; + gcptr *items = d->abortinfo.items; + for (i = 0; i < size; i += 2) { + visit(&items[i]); + /* items[i+1] is not a gc ptr */ + } + + struct tx_abort_info *ai = (struct tx_abort_info *)d->longest_abort_info; + if (ai != NULL && ai->signature_packed == 127) { + revision_t *src = ai->words; + while (*src != 0) { + gcptr *rpps; + + switch (*src++) { + + case 1: /* signed */ + case 2: /* unsigned */ + src++; /* ignore the value */ + break; + + case 3: + rpps = (gcptr *)(src++); + src++; /* ignore the offset */ + visit(rpps); /* visit() the string object */ + break; + } + } + } +} diff --git a/rpython/translator/stm/src_stm/extra.h b/rpython/translator/stm/src_stm/extra.h --- a/rpython/translator/stm/src_stm/extra.h +++ b/rpython/translator/stm/src_stm/extra.h @@ -3,8 +3,20 @@ #define _SRCSTM_EXTRA_H +struct tx_abort_info { + char signature_packed; /* 127 when the abort_info is in this format */ + long long elapsed_time; + int abort_reason; + int active; + long atomic; + unsigned long count_reads; + unsigned long reads_size_limit_nonatomic; + revision_t words[1]; /* the 'words' list is a bytecode-like format */ +}; + void stm_copy_to_old_id_copy(gcptr obj, gcptr id); size_t stm_decode_abort_info(struct tx_descriptor *d, long long elapsed_time, - int abort_reason, char *output); + int abort_reason, struct tx_abort_info *output); +void stm_visit_abort_info(struct tx_descriptor *d, void (*visit)(gcptr *)); #endif diff --git a/rpython/translator/stm/src_stm/gcpage.c b/rpython/translator/stm/src_stm/gcpage.c --- a/rpython/translator/stm/src_stm/gcpage.c +++ b/rpython/translator/stm/src_stm/gcpage.c @@ -563,12 +563,7 @@ visit_take_protected(&d->old_thread_local_obj); /* the abortinfo objects */ - long i, size = d->abortinfo.size; - gcptr *items = d->abortinfo.items; - for (i = 0; i < size; i += 2) { - visit_take_protected(&items[i]); - /* items[i+1] is not a gc ptr */ - } + stm_visit_abort_info(d, &visit_take_protected); /* the current transaction's private copies of public objects */ wlog_t *item; @@ -601,8 +596,8 @@ } G2L_LOOP_END; /* reinsert to real pub_to_priv */ - size = new_public_to_private.size; - items = new_public_to_private.items; + long i, size = new_public_to_private.size; + gcptr *items = new_public_to_private.items; for (i = 0; i < size; i += 2) { g2l_insert(&d->public_to_private, items[i], items[i + 1]); } diff --git a/rpython/translator/stm/src_stm/nursery.c b/rpython/translator/stm/src_stm/nursery.c --- a/rpython/translator/stm/src_stm/nursery.c +++ b/rpython/translator/stm/src_stm/nursery.c @@ -456,12 +456,7 @@ visit_if_young(d->thread_local_obj_ref); visit_if_young(&d->old_thread_local_obj); - long i, size = d->abortinfo.size; - gcptr *items = d->abortinfo.items; - for (i = 0; i < size; i += 2) { - visit_if_young(&items[i]); - /* items[i+1] is not a gc ptr */ - } + stm_visit_abort_info(d, &visit_if_young); } static void minor_collect(struct tx_descriptor *d) diff --git a/rpython/translator/stm/src_stm/revision b/rpython/translator/stm/src_stm/revision --- a/rpython/translator/stm/src_stm/revision +++ b/rpython/translator/stm/src_stm/revision @@ -1,1 +1,1 @@ -8b92101281e9 +24b6be3aaa67 diff --git a/rpython/translator/stm/src_stm/stmgc.h b/rpython/translator/stm/src_stm/stmgc.h --- a/rpython/translator/stm/src_stm/stmgc.h +++ b/rpython/translator/stm/src_stm/stmgc.h @@ -155,7 +155,7 @@ stm_inspect_abort_info(). (XXX details not documented yet) */ void stm_abort_info_push(gcptr obj, long fieldoffsets[]); void stm_abort_info_pop(long count); -char *stm_inspect_abort_info(void); +char *stm_inspect_abort_info(void); /* turns inevitable */ /* mostly for debugging support */ void stm_abort_and_retry(void); From noreply at buildbot.pypy.org Fri Sep 6 21:24:14 2013 From: noreply at buildbot.pypy.org (arigo) Date: Fri, 6 Sep 2013 21:24:14 +0200 (CEST) Subject: [pypy-commit] pypy stmgc-c4: Re-enable printing conflicts, which seems to work fine now. Message-ID: <20130906192414.26D031C02CD@cobra.cs.uni-duesseldorf.de> Author: Armin Rigo Branch: stmgc-c4 Changeset: r66822:3c31bf7fd9ce Date: 2013-09-06 21:23 +0200 http://bitbucket.org/pypy/pypy/changeset/3c31bf7fd9ce/ Log: Re-enable printing conflicts, which seems to work fine now. diff --git a/lib_pypy/transaction.py b/lib_pypy/transaction.py --- a/lib_pypy/transaction.py +++ b/lib_pypy/transaction.py @@ -229,15 +229,13 @@ while True: with signals_enabled: with atomic: - # XXX the call to report_abort_info() is disabled for - # XXX now because it's buggy - #info = last_abort_info() - #if info is None: + info = last_abort_info() + if info is None: if not got_exception: f(*args, **kwds) # else return early if already an exc to reraise return - #report_abort_info(info) + report_abort_info(info) except: got_exception[:] = sys.exc_info() From noreply at buildbot.pypy.org Fri Sep 6 22:31:35 2013 From: noreply at buildbot.pypy.org (arigo) Date: Fri, 6 Sep 2013 22:31:35 +0200 (CEST) Subject: [pypy-commit] pypy stmgc-c4: Make the __thread in these files only appear in stm mode. Message-ID: <20130906203135.3E55A1C00EC@cobra.cs.uni-duesseldorf.de> Author: Armin Rigo Branch: stmgc-c4 Changeset: r66823:bb1e13c5f0d1 Date: 2013-09-06 22:25 +0200 http://bitbucket.org/pypy/pypy/changeset/bb1e13c5f0d1/ Log: Make the __thread in these files only appear in stm mode. diff --git a/rpython/translator/c/src/debug_print.c b/rpython/translator/c/src/debug_print.c --- a/rpython/translator/c/src/debug_print.c +++ b/rpython/translator/c/src/debug_print.c @@ -15,13 +15,13 @@ #include "src/profiling.h" #include "src/debug_print.h" -__thread long pypy_have_debug_prints = -1; +__thread_if_stm long pypy_have_debug_prints = -1; FILE *pypy_debug_file = NULL; /* XXX make it thread-local too? */ static unsigned char debug_ready = 0; static unsigned char debug_profile = 0; -__thread char debug_start_colors_1[32]; -__thread char debug_start_colors_2[28]; -__thread char pypy_debug_threadid[16]; +__thread_if_stm static char debug_start_colors_1[32]; +__thread_if_stm static char debug_start_colors_2[28]; +__thread_if_stm char pypy_debug_threadid[16] = {0}; static char *debug_stop_colors = ""; static char *debug_prefix = NULL; static char *debug_filename = NULL; @@ -184,7 +184,9 @@ /* not a tty output: no colors */ sprintf(debug_start_colors_1, "%d# ", (int)counter); sprintf(debug_start_colors_2, "%d# ", (int)counter); +#ifdef RPY_STM sprintf(pypy_debug_threadid, "%d#", (int)counter); +#endif } else { /* tty output */ @@ -200,8 +202,10 @@ color, (int)counter); sprintf(debug_start_colors_2, "\033[%dm%d# ", color, (int)counter); +#ifdef RPY_STM sprintf(pypy_debug_threadid, "\033[%dm%d#\033[0m", color, (int)counter); +#endif } } diff --git a/rpython/translator/c/src/debug_print.h b/rpython/translator/c/src/debug_print.h --- a/rpython/translator/c/src/debug_print.h +++ b/rpython/translator/c/src/debug_print.h @@ -42,8 +42,14 @@ long pypy_debug_offset(void); void pypy_debug_forked(long original_offset); -extern __thread long pypy_have_debug_prints; -extern __thread char pypy_debug_threadid[]; +#ifdef RPY_STM +#define __thread_if_stm __thread +#else +#define __thread_if_stm /* nothing */ +#endif + +extern __thread_if_stm long pypy_have_debug_prints; +extern __thread_if_stm char pypy_debug_threadid[]; extern FILE *pypy_debug_file; #define OP_LL_READ_TIMESTAMP(val) READ_TIMESTAMP(val) From noreply at buildbot.pypy.org Fri Sep 6 22:31:36 2013 From: noreply at buildbot.pypy.org (arigo) Date: Fri, 6 Sep 2013 22:31:36 +0200 (CEST) Subject: [pypy-commit] pypy stmgc-c4: Make the __thread in these files only appear in stm mode. Message-ID: <20130906203136.8B7031C02CD@cobra.cs.uni-duesseldorf.de> Author: Armin Rigo Branch: stmgc-c4 Changeset: r66824:14394c24ac4d Date: 2013-09-06 22:28 +0200 http://bitbucket.org/pypy/pypy/changeset/14394c24ac4d/ Log: Make the __thread in these files only appear in stm mode. diff --git a/rpython/translator/c/src/rtyper.c b/rpython/translator/c/src/rtyper.c --- a/rpython/translator/c/src/rtyper.c +++ b/rpython/translator/c/src/rtyper.c @@ -9,7 +9,13 @@ #include #include -__thread struct _RPyString_dump_t { +#ifdef RPY_STM +#define __thread_if_stm __thread +#else +#define __thread_if_stm /* nothing */ +#endif + +__thread_if_stm struct _RPyString_dump_t { struct _RPyString_dump_t *next; char data[1]; } *_RPyString_dump = NULL; From noreply at buildbot.pypy.org Fri Sep 6 22:31:37 2013 From: noreply at buildbot.pypy.org (arigo) Date: Fri, 6 Sep 2013 22:31:37 +0200 (CEST) Subject: [pypy-commit] pypy stmgc-c4: merge heads Message-ID: <20130906203137.E78751C00EC@cobra.cs.uni-duesseldorf.de> Author: Armin Rigo Branch: stmgc-c4 Changeset: r66825:42b90135f84b Date: 2013-09-06 22:30 +0200 http://bitbucket.org/pypy/pypy/changeset/42b90135f84b/ Log: merge heads diff --git a/pypy/module/__pypy__/interp_signal.py b/pypy/module/__pypy__/interp_signal.py --- a/pypy/module/__pypy__/interp_signal.py +++ b/pypy/module/__pypy__/interp_signal.py @@ -1,6 +1,9 @@ +from rpython.rlib import jit + at jit.dont_look_inside def signals_enter(space): space.threadlocals.enable_signals(space) + at jit.dont_look_inside def signals_exit(space, w_ignored1=None, w_ignored2=None, w_ignored3=None): space.threadlocals.disable_signals(space) diff --git a/pypy/module/thread/stm.py b/pypy/module/thread/stm.py --- a/pypy/module/thread/stm.py +++ b/pypy/module/thread/stm.py @@ -28,6 +28,7 @@ if not we_are_translated() and not hasattr(ec, '_thread_local_dicts'): initialize_execution_context(ec) + at jit.dont_look_inside # XXX: handle abort_info_push in JIT def enter_frame(ec, frame): """Called from ExecutionContext.enter().""" if frame.hide(): diff --git a/rpython/rlib/rstm.py b/rpython/rlib/rstm.py --- a/rpython/rlib/rstm.py +++ b/rpython/rlib/rstm.py @@ -58,7 +58,6 @@ def is_atomic(): return llop.stm_get_atomic(lltype.Signed) - at dont_look_inside def abort_info_push(instance, fieldnames): "Special-cased below." diff --git a/rpython/translator/stm/src_stm/et.c b/rpython/translator/stm/src_stm/et.c --- a/rpython/translator/stm/src_stm/et.c +++ b/rpython/translator/stm/src_stm/et.c @@ -25,7 +25,7 @@ } cur += sprintf(cur, "tid=%ld", stm_get_tid(obj)); cur += sprintf(cur, " : rev=%lx : orig=%lx", - obj->h_revision, obj->h_original); + (long)obj->h_revision, (long)obj->h_original); return tmp_buf; } @@ -951,8 +951,8 @@ d->longest_abort_info_time = 0; /* out of memory! */ else { - if (stm_decode_abort_info(d, elapsed_time, - num, d->longest_abort_info) != size) + if (stm_decode_abort_info(d, elapsed_time, num, + (struct tx_abort_info *)d->longest_abort_info) != size) stm_fatalerror("during stm abort: object mutated unexpectedly\n"); d->longest_abort_info_time = elapsed_time; diff --git a/rpython/translator/stm/src_stm/extra.c b/rpython/translator/stm/src_stm/extra.c --- a/rpython/translator/stm/src_stm/extra.c +++ b/rpython/translator/stm/src_stm/extra.c @@ -236,13 +236,75 @@ } size_t stm_decode_abort_info(struct tx_descriptor *d, long long elapsed_time, - int abort_reason, char *output) + int abort_reason, struct tx_abort_info *output) { - /* re-encodes the abort info as a single string. + /* Re-encodes the abort info as a single tx_abort_info structure. + This struct tx_abort_info is not visible to the outside, and used + only as an intermediate format that is fast to generate and without + requiring stm_read_barrier(). + */ + if (output != NULL) { + output->signature_packed = 127; + output->elapsed_time = elapsed_time; + output->abort_reason = abort_reason; + output->active = d->active; + output->atomic = d->atomic; + output->count_reads = d->count_reads; + output->reads_size_limit_nonatomic = d->reads_size_limit_nonatomic; + } + + long num_words = 0; +#define WRITE_WORD(word) { \ + if (output) output->words[num_words] = (word); \ + num_words++; \ + } + + long i; + for (i=0; iabortinfo.size; i+=2) { + char *object = (char*)stm_repeat_read_barrier(d->abortinfo.items[i+0]); + long *fieldoffsets = (long*)d->abortinfo.items[i+1]; + long kind, offset; + while (*fieldoffsets != 0) { + kind = *fieldoffsets++; + WRITE_WORD(kind); + if (kind < 0) { + /* -1 is start of sublist; -2 is end of sublist */ + continue; + } + offset = *fieldoffsets++; + switch(kind) { + case 1: /* signed */ + case 2: /* unsigned */ + WRITE_WORD(*(long *)(object + offset)); + break; + case 3: /* a string of bytes from the target object */ + WRITE_WORD((revision_t)*(char **)(object + offset)); + offset = *fieldoffsets++; /* offset of len in the string */ + WRITE_WORD(offset); + break; + default: + stm_fatalerror("corrupted abort log\n"); + } + } + } + WRITE_WORD(0); +#undef WRITE_WORD + return sizeof(struct tx_abort_info) + (num_words - 1) * sizeof(revision_t); +} + +static size_t unpack_abort_info(struct tx_descriptor *d, + struct tx_abort_info *ai, + char *output) +{ + /* Lazily decodes a struct tx_abort_info into a single plain string. For convenience (no escaping needed, no limit on integer - sizes, etc.) we follow the bittorrent format. */ + sizes, etc.) we follow the bittorrent format. This makes the + format a bit more flexible for future changes. The struct + tx_abort_info is still needed as an intermediate step, because + the string parameters may not be readable during an abort + (they may be stubs). + */ size_t totalsize = 0; - long i; char buffer[32]; size_t res_size; #define WRITE(c) { totalsize++; if (output) *output++=(c); } @@ -253,75 +315,74 @@ } WRITE('l'); WRITE('l'); - res_size = sprintf(buffer, "i%llde", (long long)elapsed_time); + res_size = sprintf(buffer, "i%llde", (long long)ai->elapsed_time); WRITE_BUF(buffer, res_size); - res_size = sprintf(buffer, "i%de", (int)abort_reason); + res_size = sprintf(buffer, "i%de", (int)ai->abort_reason); WRITE_BUF(buffer, res_size); res_size = sprintf(buffer, "i%lde", (long)d->public_descriptor_index); WRITE_BUF(buffer, res_size); - res_size = sprintf(buffer, "i%lde", (long)d->atomic); + res_size = sprintf(buffer, "i%lde", (long)ai->atomic); WRITE_BUF(buffer, res_size); - res_size = sprintf(buffer, "i%de", (int)d->active); + res_size = sprintf(buffer, "i%de", (int)ai->active); WRITE_BUF(buffer, res_size); - res_size = sprintf(buffer, "i%lue", (unsigned long)d->count_reads); + res_size = sprintf(buffer, "i%lue", (unsigned long)ai->count_reads); WRITE_BUF(buffer, res_size); res_size = sprintf(buffer, "i%lue", - (unsigned long)d->reads_size_limit_nonatomic); + (unsigned long)ai->reads_size_limit_nonatomic); WRITE_BUF(buffer, res_size); WRITE('e'); - for (i=0; iabortinfo.size; i+=2) { - char *object = (char*)stm_repeat_read_barrier(d->abortinfo.items[i+0]); - long *fieldoffsets = (long*)d->abortinfo.items[i+1]; - long kind, offset; - size_t rps_size; + + revision_t *src = ai->words; + while (*src != 0) { + long signed_value; + unsigned long unsigned_value; char *rps; + long offset, rps_size; - while (1) { - kind = *fieldoffsets++; - if (kind <= 0) { - if (kind == -2) { - WRITE('l'); /* '[', start of sublist */ - continue; - } - if (kind == -1) { - WRITE('e'); /* ']', end of sublist */ - continue; - } - break; /* 0, terminator */ + switch (*src++) { + + case -2: + WRITE('l'); /* '[', start of sublist */ + break; + + case -1: + WRITE('e'); /* ']', end of sublist */ + break; + + case 1: /* signed */ + signed_value = (long)(*src++); + res_size = sprintf(buffer, "i%lde", signed_value); + WRITE_BUF(buffer, res_size); + break; + + case 2: /* unsigned */ + unsigned_value = (unsigned long)(*src++); + res_size = sprintf(buffer, "i%lue", unsigned_value); + WRITE_BUF(buffer, res_size); + break; + + case 3: /* a string of bytes from the target object */ + rps = (char *)(*src++); + offset = *src++; + if (rps) { + rps = (char *)stm_read_barrier((gcptr)rps); + /* xxx a bit ad-hoc: it's a string whose length is a + * long at 'rps_size'; the string data follows + * immediately the length */ + rps_size = *(long *)(rps + offset); + assert(rps_size >= 0); + res_size = sprintf(buffer, "%ld:", rps_size); + WRITE_BUF(buffer, res_size); + WRITE_BUF(rps + offset + sizeof(long), rps_size); } - offset = *fieldoffsets++; - switch(kind) { - case 1: /* signed */ - res_size = sprintf(buffer, "i%lde", - *(long*)(object + offset)); - WRITE_BUF(buffer, res_size); - break; - case 2: /* unsigned */ - res_size = sprintf(buffer, "i%lue", - *(unsigned long*)(object + offset)); - WRITE_BUF(buffer, res_size); - break; - case 3: /* a string of bytes from the target object */ - rps = *(char **)(object + offset); - offset = *fieldoffsets++; - /* XXX think of a different hack: this one doesn't really - work if we see stubs! */ - if (rps && !(((gcptr)rps)->h_tid & GCFLAG_STUB)) { - /* xxx a bit ad-hoc: it's a string whose length is a - * long at 'offset', following immediately the offset */ - rps_size = *(long *)(rps + offset); - assert(rps_size >= 0); - res_size = sprintf(buffer, "%zu:", rps_size); - WRITE_BUF(buffer, res_size); - WRITE_BUF(rps + offset + sizeof(long), rps_size); - } - else { - WRITE_BUF("0:", 2); - } - break; - default: - stm_fatalerror("corrupted abort log\n"); + else { + /* write NULL as an empty string, good enough for now */ + WRITE_BUF("0:", 2); } + break; + + default: + stm_fatalerror("corrupted abort log\n"); } } WRITE('e'); @@ -336,6 +397,53 @@ struct tx_descriptor *d = thread_descriptor; if (d->longest_abort_info_time <= 0) return NULL; + + struct tx_abort_info *ai = (struct tx_abort_info *)d->longest_abort_info; + assert(ai->signature_packed == 127); + + stm_become_inevitable("stm_inspect_abort_info"); + + size_t size = unpack_abort_info(d, ai, NULL); + char *text = malloc(size); + if (text == NULL) + return NULL; /* out of memory */ + if (unpack_abort_info(d, ai, text) != size) + stm_fatalerror("stm_inspect_abort_info: " + "object mutated unexpectedly\n"); + free(ai); + d->longest_abort_info = text; d->longest_abort_info_time = 0; return d->longest_abort_info; } + +void stm_visit_abort_info(struct tx_descriptor *d, void (*visit)(gcptr *)) +{ + long i, size = d->abortinfo.size; + gcptr *items = d->abortinfo.items; + for (i = 0; i < size; i += 2) { + visit(&items[i]); + /* items[i+1] is not a gc ptr */ + } + + struct tx_abort_info *ai = (struct tx_abort_info *)d->longest_abort_info; + if (ai != NULL && ai->signature_packed == 127) { + revision_t *src = ai->words; + while (*src != 0) { + gcptr *rpps; + + switch (*src++) { + + case 1: /* signed */ + case 2: /* unsigned */ + src++; /* ignore the value */ + break; + + case 3: + rpps = (gcptr *)(src++); + src++; /* ignore the offset */ + visit(rpps); /* visit() the string object */ + break; + } + } + } +} diff --git a/rpython/translator/stm/src_stm/extra.h b/rpython/translator/stm/src_stm/extra.h --- a/rpython/translator/stm/src_stm/extra.h +++ b/rpython/translator/stm/src_stm/extra.h @@ -3,8 +3,20 @@ #define _SRCSTM_EXTRA_H +struct tx_abort_info { + char signature_packed; /* 127 when the abort_info is in this format */ + long long elapsed_time; + int abort_reason; + int active; + long atomic; + unsigned long count_reads; + unsigned long reads_size_limit_nonatomic; + revision_t words[1]; /* the 'words' list is a bytecode-like format */ +}; + void stm_copy_to_old_id_copy(gcptr obj, gcptr id); size_t stm_decode_abort_info(struct tx_descriptor *d, long long elapsed_time, - int abort_reason, char *output); + int abort_reason, struct tx_abort_info *output); +void stm_visit_abort_info(struct tx_descriptor *d, void (*visit)(gcptr *)); #endif diff --git a/rpython/translator/stm/src_stm/gcpage.c b/rpython/translator/stm/src_stm/gcpage.c --- a/rpython/translator/stm/src_stm/gcpage.c +++ b/rpython/translator/stm/src_stm/gcpage.c @@ -563,12 +563,7 @@ visit_take_protected(&d->old_thread_local_obj); /* the abortinfo objects */ - long i, size = d->abortinfo.size; - gcptr *items = d->abortinfo.items; - for (i = 0; i < size; i += 2) { - visit_take_protected(&items[i]); - /* items[i+1] is not a gc ptr */ - } + stm_visit_abort_info(d, &visit_take_protected); /* the current transaction's private copies of public objects */ wlog_t *item; @@ -601,8 +596,8 @@ } G2L_LOOP_END; /* reinsert to real pub_to_priv */ - size = new_public_to_private.size; - items = new_public_to_private.items; + long i, size = new_public_to_private.size; + gcptr *items = new_public_to_private.items; for (i = 0; i < size; i += 2) { g2l_insert(&d->public_to_private, items[i], items[i + 1]); } diff --git a/rpython/translator/stm/src_stm/nursery.c b/rpython/translator/stm/src_stm/nursery.c --- a/rpython/translator/stm/src_stm/nursery.c +++ b/rpython/translator/stm/src_stm/nursery.c @@ -456,12 +456,7 @@ visit_if_young(d->thread_local_obj_ref); visit_if_young(&d->old_thread_local_obj); - long i, size = d->abortinfo.size; - gcptr *items = d->abortinfo.items; - for (i = 0; i < size; i += 2) { - visit_if_young(&items[i]); - /* items[i+1] is not a gc ptr */ - } + stm_visit_abort_info(d, &visit_if_young); } static void minor_collect(struct tx_descriptor *d) diff --git a/rpython/translator/stm/src_stm/revision b/rpython/translator/stm/src_stm/revision --- a/rpython/translator/stm/src_stm/revision +++ b/rpython/translator/stm/src_stm/revision @@ -1,1 +1,1 @@ -8b92101281e9 +24b6be3aaa67 diff --git a/rpython/translator/stm/src_stm/stmgc.h b/rpython/translator/stm/src_stm/stmgc.h --- a/rpython/translator/stm/src_stm/stmgc.h +++ b/rpython/translator/stm/src_stm/stmgc.h @@ -155,7 +155,7 @@ stm_inspect_abort_info(). (XXX details not documented yet) */ void stm_abort_info_push(gcptr obj, long fieldoffsets[]); void stm_abort_info_pop(long count); -char *stm_inspect_abort_info(void); +char *stm_inspect_abort_info(void); /* turns inevitable */ /* mostly for debugging support */ void stm_abort_and_retry(void); From noreply at buildbot.pypy.org Sat Sep 7 01:38:15 2013 From: noreply at buildbot.pypy.org (pjenvey) Date: Sat, 7 Sep 2013 01:38:15 +0200 (CEST) Subject: [pypy-commit] buildbot default: cleanup artifacts (.pycs in particular) between builds Message-ID: <20130906233815.A588F1C03F4@cobra.cs.uni-duesseldorf.de> Author: Philip Jenvey Branch: Changeset: r858:2afccc220989 Date: 2013-09-06 16:38 -0700 http://bitbucket.org/pypy/buildbot/changeset/2afccc220989/ Log: cleanup artifacts (.pycs in particular) between builds diff --git a/bot2/pypybuildbot/builds.py b/bot2/pypybuildbot/builds.py --- a/bot2/pypybuildbot/builds.py +++ b/bot2/pypybuildbot/builds.py @@ -194,7 +194,7 @@ factory.addStep( Mercurial( repourl=repourl, - mode='incremental', + mode='full', method='fresh', defaultBranch=force_branch, branchType='inrepo', From noreply at buildbot.pypy.org Sat Sep 7 13:52:32 2013 From: noreply at buildbot.pypy.org (Raemi) Date: Sat, 7 Sep 2013 13:52:32 +0200 (CEST) Subject: [pypy-commit] pypy stmgc-c4: merge default and fix "__thread before static" error in debug_print.c Message-ID: <20130907115232.4952E1C002A@cobra.cs.uni-duesseldorf.de> Author: Remi Meier Branch: stmgc-c4 Changeset: r66826:92cab05fc583 Date: 2013-09-07 13:51 +0200 http://bitbucket.org/pypy/pypy/changeset/92cab05fc583/ Log: merge default and fix "__thread before static" error in debug_print.c diff --git a/lib_pypy/_tkinter/tklib.py b/lib_pypy/_tkinter/tklib.py --- a/lib_pypy/_tkinter/tklib.py +++ b/lib_pypy/_tkinter/tklib.py @@ -1,6 +1,7 @@ # C bindings with libtcl and libtk. from cffi import FFI +import sys tkffi = FFI() @@ -102,6 +103,17 @@ int Tk_GetNumMainWindows(); """) +# XXX find a better way to detect paths +# XXX pick up CPPFLAGS and LDFLAGS and add to these paths? +if sys.platform.startswith("openbsd"): + incdirs = ['/usr/local/include/tcl8.5', '/usr/local/include/tk8.5', '/usr/X11R6/include'] + linklibs = ['tk85', 'tcl85'] + libdirs = ['/usr/local/lib', '/usr/X11R6/lib'] +else: + incdirs=['/usr/include/tcl'], + linklibs=['tcl', 'tk'], + libdirs = [] + tklib = tkffi.verify(""" #include #include @@ -109,6 +121,7 @@ char *get_tk_version() { return TK_VERSION; } char *get_tcl_version() { return TCL_VERSION; } """, -include_dirs=['/usr/include/tcl'], -libraries=['tcl', 'tk'], +include_dirs=incdirs, +libraries=linklibs, +library_dirs = libdirs ) diff --git a/pypy/interpreter/baseobjspace.py b/pypy/interpreter/baseobjspace.py --- a/pypy/interpreter/baseobjspace.py +++ b/pypy/interpreter/baseobjspace.py @@ -77,12 +77,12 @@ raise NotImplementedError("only for interp-level user subclasses " "from typedef.py") - def getname(self, space, default='?'): + def getname(self, space): try: return space.str_w(space.getattr(self, space.wrap('__name__'))) except OperationError, e: if e.match(space, space.w_TypeError) or e.match(space, space.w_AttributeError): - return default + return '?' raise def getaddrstring(self, space): diff --git a/pypy/interpreter/function.py b/pypy/interpreter/function.py --- a/pypy/interpreter/function.py +++ b/pypy/interpreter/function.py @@ -482,17 +482,16 @@ space.abstract_isinstance_w(w_firstarg, self.w_class)): pass # ok else: - clsdescr = self.w_class.getname(space, "") - if clsdescr: + clsdescr = self.w_class.getname(space) + if clsdescr and clsdescr != '?': clsdescr += " instance" else: clsdescr = "instance" if w_firstarg is None: instdescr = "nothing" else: - instname = space.abstract_getclass(w_firstarg).getname(space, - "") - if instname: + instname = space.abstract_getclass(w_firstarg).getname(space) + if instname and instname != '?': instdescr = instname + " instance" else: instdescr = "instance" diff --git a/pypy/interpreter/test/test_argument.py b/pypy/interpreter/test/test_argument.py --- a/pypy/interpreter/test/test_argument.py +++ b/pypy/interpreter/test/test_argument.py @@ -128,7 +128,7 @@ def type(self, obj): class Type: - def getname(self, space, default='?'): + def getname(self, space): return type(obj).__name__ return Type() 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 @@ -26,6 +26,9 @@ def try_ldflags(): yield ExternalCompilationInfo(libraries=['curses']) yield ExternalCompilationInfo(libraries=['curses', 'tinfo']) + yield ExternalCompilationInfo(libraries=['ncurses']) + yield ExternalCompilationInfo(libraries=['ncurses'], + library_dirs=['/usr/lib64']) def try_tools(): try: 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 @@ -175,8 +175,8 @@ state = '; dead' else: typename = space.type(w_obj).getname(space) - objname = w_obj.getname(space, '') - if objname: + objname = w_obj.getname(space) + if objname and objname != '?': state = "; to '%s' (%s)" % (typename, objname) else: state = "; to '%s'" % (typename,) diff --git a/pypy/objspace/descroperation.py b/pypy/objspace/descroperation.py --- a/pypy/objspace/descroperation.py +++ b/pypy/objspace/descroperation.py @@ -597,8 +597,8 @@ if num1 != num2: lt = num1 # if obj1 is a number, it is Lower Than obj2 else: - name1 = w_typ1.getname(space, "") - name2 = w_typ2.getname(space, "") + name1 = w_typ1.getname(space) + name2 = w_typ2.getname(space) if name1 != name2: lt = name1 < name2 else: 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 @@ -502,6 +502,12 @@ else: return w_self.name + def getname(w_self, space): + name = w_self.name + if name is None: + name = '?' + return name + def add_subclass(w_self, w_subclass): space = w_self.space if not space.config.translation.rweakref: 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 @@ -28,6 +28,7 @@ from rpython.rlib.rarithmetic import r_longlong, r_uint from rpython.rtyper.lltypesystem.lloperation import llop from rpython.rtyper.lltypesystem import lltype, rffi, rstr +from rpython.rtyper.lltypesystem.lloperation import llop class X86RegisterManager(RegisterManager): diff --git a/rpython/rtyper/test/test_rclass.py b/rpython/rtyper/test/test_rclass.py --- a/rpython/rtyper/test/test_rclass.py +++ b/rpython/rtyper/test/test_rclass.py @@ -1192,3 +1192,19 @@ assert self.interpret(f, [True]) == f(True) assert self.interpret(f, [False]) == f(False) + + def test_init_with_star_args(self): + class Base(object): + def __init__(self, a, b): + self.a = a + self.b = b + class A(Base): + def __init__(self, *args): + Base.__init__(self, *args) + self.c = -1 + cls = [Base, A] + + def f(k, a, b): + return cls[k](a, b).b + + assert self.interpret(f, [1, 4, 7]) == 7 diff --git a/rpython/translator/c/src/debug_print.c b/rpython/translator/c/src/debug_print.c --- a/rpython/translator/c/src/debug_print.c +++ b/rpython/translator/c/src/debug_print.c @@ -19,8 +19,8 @@ FILE *pypy_debug_file = NULL; /* XXX make it thread-local too? */ static unsigned char debug_ready = 0; static unsigned char debug_profile = 0; -__thread_if_stm static char debug_start_colors_1[32]; -__thread_if_stm static char debug_start_colors_2[28]; +static __thread_if_stm char debug_start_colors_1[32]; +static __thread_if_stm char debug_start_colors_2[28]; __thread_if_stm char pypy_debug_threadid[16] = {0}; static char *debug_stop_colors = ""; static char *debug_prefix = NULL; From noreply at buildbot.pypy.org Sat Sep 7 14:36:40 2013 From: noreply at buildbot.pypy.org (Raemi) Date: Sat, 7 Sep 2013 14:36:40 +0200 (CEST) Subject: [pypy-commit] pypy stmgc-c4: import stmgc Message-ID: <20130907123640.0F7AE1D2371@cobra.cs.uni-duesseldorf.de> Author: Remi Meier Branch: stmgc-c4 Changeset: r66827:bdd86d602300 Date: 2013-09-07 14:35 +0200 http://bitbucket.org/pypy/pypy/changeset/bdd86d602300/ Log: import stmgc diff --git a/rpython/translator/stm/src_stm/et.c b/rpython/translator/stm/src_stm/et.c --- a/rpython/translator/stm/src_stm/et.c +++ b/rpython/translator/stm/src_stm/et.c @@ -25,7 +25,7 @@ } cur += sprintf(cur, "tid=%ld", stm_get_tid(obj)); cur += sprintf(cur, " : rev=%lx : orig=%lx", - (long)obj->h_revision, (long)obj->h_original); + obj->h_revision, obj->h_original); return tmp_buf; } @@ -951,8 +951,8 @@ d->longest_abort_info_time = 0; /* out of memory! */ else { - if (stm_decode_abort_info(d, elapsed_time, num, - (struct tx_abort_info *)d->longest_abort_info) != size) + if (stm_decode_abort_info(d, elapsed_time, + num, d->longest_abort_info) != size) stm_fatalerror("during stm abort: object mutated unexpectedly\n"); d->longest_abort_info_time = elapsed_time; diff --git a/rpython/translator/stm/src_stm/extra.c b/rpython/translator/stm/src_stm/extra.c --- a/rpython/translator/stm/src_stm/extra.c +++ b/rpython/translator/stm/src_stm/extra.c @@ -236,75 +236,13 @@ } size_t stm_decode_abort_info(struct tx_descriptor *d, long long elapsed_time, - int abort_reason, struct tx_abort_info *output) + int abort_reason, char *output) { - /* Re-encodes the abort info as a single tx_abort_info structure. - This struct tx_abort_info is not visible to the outside, and used - only as an intermediate format that is fast to generate and without - requiring stm_read_barrier(). - */ - if (output != NULL) { - output->signature_packed = 127; - output->elapsed_time = elapsed_time; - output->abort_reason = abort_reason; - output->active = d->active; - output->atomic = d->atomic; - output->count_reads = d->count_reads; - output->reads_size_limit_nonatomic = d->reads_size_limit_nonatomic; - } - - long num_words = 0; -#define WRITE_WORD(word) { \ - if (output) output->words[num_words] = (word); \ - num_words++; \ - } - + /* re-encodes the abort info as a single string. + For convenience (no escaping needed, no limit on integer + sizes, etc.) we follow the bittorrent format. */ + size_t totalsize = 0; long i; - for (i=0; iabortinfo.size; i+=2) { - char *object = (char*)stm_repeat_read_barrier(d->abortinfo.items[i+0]); - long *fieldoffsets = (long*)d->abortinfo.items[i+1]; - long kind, offset; - while (*fieldoffsets != 0) { - kind = *fieldoffsets++; - WRITE_WORD(kind); - if (kind < 0) { - /* -1 is start of sublist; -2 is end of sublist */ - continue; - } - offset = *fieldoffsets++; - switch(kind) { - case 1: /* signed */ - case 2: /* unsigned */ - WRITE_WORD(*(long *)(object + offset)); - break; - case 3: /* a string of bytes from the target object */ - WRITE_WORD((revision_t)*(char **)(object + offset)); - offset = *fieldoffsets++; /* offset of len in the string */ - WRITE_WORD(offset); - break; - default: - stm_fatalerror("corrupted abort log\n"); - } - } - } - WRITE_WORD(0); -#undef WRITE_WORD - return sizeof(struct tx_abort_info) + (num_words - 1) * sizeof(revision_t); -} - -static size_t unpack_abort_info(struct tx_descriptor *d, - struct tx_abort_info *ai, - char *output) -{ - /* Lazily decodes a struct tx_abort_info into a single plain string. - For convenience (no escaping needed, no limit on integer - sizes, etc.) we follow the bittorrent format. This makes the - format a bit more flexible for future changes. The struct - tx_abort_info is still needed as an intermediate step, because - the string parameters may not be readable during an abort - (they may be stubs). - */ - size_t totalsize = 0; char buffer[32]; size_t res_size; #define WRITE(c) { totalsize++; if (output) *output++=(c); } @@ -315,74 +253,75 @@ } WRITE('l'); WRITE('l'); - res_size = sprintf(buffer, "i%llde", (long long)ai->elapsed_time); + res_size = sprintf(buffer, "i%llde", (long long)elapsed_time); WRITE_BUF(buffer, res_size); - res_size = sprintf(buffer, "i%de", (int)ai->abort_reason); + res_size = sprintf(buffer, "i%de", (int)abort_reason); WRITE_BUF(buffer, res_size); res_size = sprintf(buffer, "i%lde", (long)d->public_descriptor_index); WRITE_BUF(buffer, res_size); - res_size = sprintf(buffer, "i%lde", (long)ai->atomic); + res_size = sprintf(buffer, "i%lde", (long)d->atomic); WRITE_BUF(buffer, res_size); - res_size = sprintf(buffer, "i%de", (int)ai->active); + res_size = sprintf(buffer, "i%de", (int)d->active); WRITE_BUF(buffer, res_size); - res_size = sprintf(buffer, "i%lue", (unsigned long)ai->count_reads); + res_size = sprintf(buffer, "i%lue", (unsigned long)d->count_reads); WRITE_BUF(buffer, res_size); res_size = sprintf(buffer, "i%lue", - (unsigned long)ai->reads_size_limit_nonatomic); + (unsigned long)d->reads_size_limit_nonatomic); WRITE_BUF(buffer, res_size); WRITE('e'); + for (i=0; iabortinfo.size; i+=2) { + char *object = (char*)stm_repeat_read_barrier(d->abortinfo.items[i+0]); + long *fieldoffsets = (long*)d->abortinfo.items[i+1]; + long kind, offset; + size_t rps_size; + char *rps; - revision_t *src = ai->words; - while (*src != 0) { - long signed_value; - unsigned long unsigned_value; - char *rps; - long offset, rps_size; - - switch (*src++) { - - case -2: - WRITE('l'); /* '[', start of sublist */ - break; - - case -1: - WRITE('e'); /* ']', end of sublist */ - break; - - case 1: /* signed */ - signed_value = (long)(*src++); - res_size = sprintf(buffer, "i%lde", signed_value); - WRITE_BUF(buffer, res_size); - break; - - case 2: /* unsigned */ - unsigned_value = (unsigned long)(*src++); - res_size = sprintf(buffer, "i%lue", unsigned_value); - WRITE_BUF(buffer, res_size); - break; - - case 3: /* a string of bytes from the target object */ - rps = (char *)(*src++); - offset = *src++; - if (rps) { - rps = (char *)stm_read_barrier((gcptr)rps); - /* xxx a bit ad-hoc: it's a string whose length is a - * long at 'rps_size'; the string data follows - * immediately the length */ - rps_size = *(long *)(rps + offset); - assert(rps_size >= 0); - res_size = sprintf(buffer, "%ld:", rps_size); + while (1) { + kind = *fieldoffsets++; + if (kind <= 0) { + if (kind == -2) { + WRITE('l'); /* '[', start of sublist */ + continue; + } + if (kind == -1) { + WRITE('e'); /* ']', end of sublist */ + continue; + } + break; /* 0, terminator */ + } + offset = *fieldoffsets++; + switch(kind) { + case 1: /* signed */ + res_size = sprintf(buffer, "i%lde", + *(long*)(object + offset)); WRITE_BUF(buffer, res_size); - WRITE_BUF(rps + offset + sizeof(long), rps_size); + break; + case 2: /* unsigned */ + res_size = sprintf(buffer, "i%lue", + *(unsigned long*)(object + offset)); + WRITE_BUF(buffer, res_size); + break; + case 3: /* a string of bytes from the target object */ + rps = *(char **)(object + offset); + offset = *fieldoffsets++; + /* XXX think of a different hack: this one doesn't really + work if we see stubs! */ + if (rps && !(((gcptr)rps)->h_tid & GCFLAG_STUB)) { + /* xxx a bit ad-hoc: it's a string whose length is a + * long at 'offset', following immediately the offset */ + rps_size = *(long *)(rps + offset); + assert(rps_size >= 0); + res_size = sprintf(buffer, "%zu:", rps_size); + WRITE_BUF(buffer, res_size); + WRITE_BUF(rps + offset + sizeof(long), rps_size); + } + else { + WRITE_BUF("0:", 2); + } + break; + default: + stm_fatalerror("corrupted abort log\n"); } - else { - /* write NULL as an empty string, good enough for now */ - WRITE_BUF("0:", 2); - } - break; - - default: - stm_fatalerror("corrupted abort log\n"); } } WRITE('e'); @@ -397,53 +336,6 @@ struct tx_descriptor *d = thread_descriptor; if (d->longest_abort_info_time <= 0) return NULL; - - struct tx_abort_info *ai = (struct tx_abort_info *)d->longest_abort_info; - assert(ai->signature_packed == 127); - - stm_become_inevitable("stm_inspect_abort_info"); - - size_t size = unpack_abort_info(d, ai, NULL); - char *text = malloc(size); - if (text == NULL) - return NULL; /* out of memory */ - if (unpack_abort_info(d, ai, text) != size) - stm_fatalerror("stm_inspect_abort_info: " - "object mutated unexpectedly\n"); - free(ai); - d->longest_abort_info = text; d->longest_abort_info_time = 0; return d->longest_abort_info; } - -void stm_visit_abort_info(struct tx_descriptor *d, void (*visit)(gcptr *)) -{ - long i, size = d->abortinfo.size; - gcptr *items = d->abortinfo.items; - for (i = 0; i < size; i += 2) { - visit(&items[i]); - /* items[i+1] is not a gc ptr */ - } - - struct tx_abort_info *ai = (struct tx_abort_info *)d->longest_abort_info; - if (ai != NULL && ai->signature_packed == 127) { - revision_t *src = ai->words; - while (*src != 0) { - gcptr *rpps; - - switch (*src++) { - - case 1: /* signed */ - case 2: /* unsigned */ - src++; /* ignore the value */ - break; - - case 3: - rpps = (gcptr *)(src++); - src++; /* ignore the offset */ - visit(rpps); /* visit() the string object */ - break; - } - } - } -} diff --git a/rpython/translator/stm/src_stm/extra.h b/rpython/translator/stm/src_stm/extra.h --- a/rpython/translator/stm/src_stm/extra.h +++ b/rpython/translator/stm/src_stm/extra.h @@ -3,20 +3,8 @@ #define _SRCSTM_EXTRA_H -struct tx_abort_info { - char signature_packed; /* 127 when the abort_info is in this format */ - long long elapsed_time; - int abort_reason; - int active; - long atomic; - unsigned long count_reads; - unsigned long reads_size_limit_nonatomic; - revision_t words[1]; /* the 'words' list is a bytecode-like format */ -}; - void stm_copy_to_old_id_copy(gcptr obj, gcptr id); size_t stm_decode_abort_info(struct tx_descriptor *d, long long elapsed_time, - int abort_reason, struct tx_abort_info *output); -void stm_visit_abort_info(struct tx_descriptor *d, void (*visit)(gcptr *)); + int abort_reason, char *output); #endif diff --git a/rpython/translator/stm/src_stm/gcpage.c b/rpython/translator/stm/src_stm/gcpage.c --- a/rpython/translator/stm/src_stm/gcpage.c +++ b/rpython/translator/stm/src_stm/gcpage.c @@ -563,7 +563,12 @@ visit_take_protected(&d->old_thread_local_obj); /* the abortinfo objects */ - stm_visit_abort_info(d, &visit_take_protected); + long i, size = d->abortinfo.size; + gcptr *items = d->abortinfo.items; + for (i = 0; i < size; i += 2) { + visit_take_protected(&items[i]); + /* items[i+1] is not a gc ptr */ + } /* the current transaction's private copies of public objects */ wlog_t *item; @@ -596,8 +601,8 @@ } G2L_LOOP_END; /* reinsert to real pub_to_priv */ - long i, size = new_public_to_private.size; - gcptr *items = new_public_to_private.items; + size = new_public_to_private.size; + items = new_public_to_private.items; for (i = 0; i < size; i += 2) { g2l_insert(&d->public_to_private, items[i], items[i + 1]); } diff --git a/rpython/translator/stm/src_stm/nursery.c b/rpython/translator/stm/src_stm/nursery.c --- a/rpython/translator/stm/src_stm/nursery.c +++ b/rpython/translator/stm/src_stm/nursery.c @@ -456,7 +456,12 @@ visit_if_young(d->thread_local_obj_ref); visit_if_young(&d->old_thread_local_obj); - stm_visit_abort_info(d, &visit_if_young); + long i, size = d->abortinfo.size; + gcptr *items = d->abortinfo.items; + for (i = 0; i < size; i += 2) { + visit_if_young(&items[i]); + /* items[i+1] is not a gc ptr */ + } } static void minor_collect(struct tx_descriptor *d) diff --git a/rpython/translator/stm/src_stm/revision b/rpython/translator/stm/src_stm/revision --- a/rpython/translator/stm/src_stm/revision +++ b/rpython/translator/stm/src_stm/revision @@ -1,1 +1,1 @@ -24b6be3aaa67 +8b92101281e9 diff --git a/rpython/translator/stm/src_stm/stmgc.h b/rpython/translator/stm/src_stm/stmgc.h --- a/rpython/translator/stm/src_stm/stmgc.h +++ b/rpython/translator/stm/src_stm/stmgc.h @@ -155,7 +155,7 @@ stm_inspect_abort_info(). (XXX details not documented yet) */ void stm_abort_info_push(gcptr obj, long fieldoffsets[]); void stm_abort_info_pop(long count); -char *stm_inspect_abort_info(void); /* turns inevitable */ +char *stm_inspect_abort_info(void); /* mostly for debugging support */ void stm_abort_and_retry(void); From noreply at buildbot.pypy.org Sat Sep 7 16:03:33 2013 From: noreply at buildbot.pypy.org (Raemi) Date: Sat, 7 Sep 2013 16:03:33 +0200 (CEST) Subject: [pypy-commit] pypy stmgc-c4: cleanup of thread-local code in assembler.py Message-ID: <20130907140333.B5F5F1C0EFC@cobra.cs.uni-duesseldorf.de> Author: Remi Meier Branch: stmgc-c4 Changeset: r66828:93f7b05a0602 Date: 2013-09-07 15:50 +0200 http://bitbucket.org/pypy/pypy/changeset/93f7b05a0602/ Log: cleanup of thread-local code in assembler.py 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 @@ -37,6 +37,7 @@ from rpython.jit.backend.x86 import stmtlocal from rpython.rlib import rstm from rpython.memory.gc.stmgc import StmGC +from rpython.jit.backend.llsupport.gc import STMBarrierDescr class Assembler386(BaseAssembler): @@ -301,13 +302,15 @@ Before using such a relative address, call self._stm_tl_segment_prefix_if_necessary.""" if self.cpu.gc_ll_descr.stm and we_are_translated(): - # also not during tests + # only for STM and not during tests result = adr - stmtlocal.threadlocal_base() assert rx86.fits_in_32bits(result) return result return adr - def _stm_tl_segment_prefix_if_necessary(self, mc): + def _tl_segment_if_stm(self, mc): + """Insert segment prefix for thread-local memory if we run + in STM and not during testing.""" if self.cpu.gc_ll_descr.stm and we_are_translated(): stmtlocal.tl_segment_prefix(mc) @@ -346,7 +349,7 @@ mc.ADD_ri(esp.value, WORD) # ea = self._get_stm_tl(self.cpu.pos_exception()) - self._stm_tl_segment_prefix_if_necessary(mc) + self._tl_segment_if_stm(mc) mc.MOV(eax, heap(ea)) mc.TEST_rr(eax.value, eax.value) mc.J_il8(rx86.Conditions['NZ'], 0) @@ -900,11 +903,9 @@ that gives the address of the stack top. If this integer doesn't fit in 32 bits, it will be loaded in r11. """ - rst = self._get_root_stack_top_addr() + rst = self._get_stm_tl(gcrootmap.get_root_stack_top_addr()) if rx86.fits_in_32bits(rst): - if gcrootmap.is_stm and we_are_translated(): - # during testing, it will be an absolute address - stmtlocal.tl_segment_prefix(mc) + self._tl_segment_if_stm(mc) mc.MOV_rj(ebx.value, rst) # MOV ebx, [rootstacktop] else: mc.MOV_ri(X86_64_SCRATCH_REG.value, rst) # MOV r11, rootstacktop @@ -932,9 +933,7 @@ self.mc.ADD_ri(ebx.value, WORD) if rx86.fits_in_32bits(rst): - if gcrootmap.is_stm and we_are_translated(): - # during testing, it will be an absolute address - stmtlocal.tl_segment_prefix(self.mc) + self._tl_segment_if_stm(self.mc) self.mc.MOV_jr(rst, ebx.value) # MOV [rootstacktop], ebx else: # The integer 'rst' doesn't fit in 32 bits, so we know that @@ -944,12 +943,9 @@ ebx.value) # MOV [r11], ebx def _call_footer_shadowstack(self, gcrootmap): - rst = self._get_root_stack_top_addr() - + rst = self._get_stm_tl(gcrootmap.get_root_stack_top_addr()) if rx86.fits_in_32bits(rst): - if gcrootmap.is_stm and we_are_translated(): - # during testing, it will be an absolute address - stmtlocal.tl_segment_prefix(self.mc) + self._tl_segment_if_stm(self.mc) self.mc.SUB_ji8(rst, WORD) # SUB [rootstacktop], WORD else: self.mc.MOV_ri(ebx.value, rst) # MOV ebx, rootstacktop @@ -1262,25 +1258,12 @@ cb = callbuilder.CallBuilder(self, fnloc, arglocs) cb.emit_no_collect() - def _get_root_stack_top_addr(self): - gcrootmap = self.cpu.gc_ll_descr.gcrootmap - - rst = gcrootmap.get_root_stack_top_addr() - if gcrootmap.is_stm and we_are_translated(): - # during testing, we return an absolute address - rst = rst - stmtlocal.threadlocal_base() - assert rx86.fits_in_32bits(rst) - return rst - def _reload_frame_if_necessary(self, mc, align_stack=False): gc_ll_descr = self.cpu.gc_ll_descr gcrootmap = gc_ll_descr.gcrootmap if gcrootmap and gcrootmap.is_shadow_stack: - rst = self._get_root_stack_top_addr() - - if gcrootmap.is_stm and we_are_translated(): - # during testing, it will be an absolute address - stmtlocal.tl_segment_prefix(mc) + rst = self._get_stm_tl(gcrootmap.get_root_stack_top_addr()) + self._tl_segment_if_stm(mc) mc.MOV(ecx, heap(rst)) mc.MOV(ebp, mem(ecx, -WORD)) # @@ -1809,7 +1792,7 @@ def genop_guard_guard_no_exception(self, ign_1, guard_op, guard_token, locs, ign_2): ea = self._get_stm_tl(self.cpu.pos_exception()) - self._stm_tl_segment_prefix_if_necessary(self.mc) + self._tl_segment_if_stm(self.mc) self.mc.CMP(heap(ea), imm0) self.implement_guard(guard_token, 'NZ') @@ -1824,7 +1807,7 @@ loc = locs[0] loc1 = locs[1] ea = self._get_stm_tl(self.cpu.pos_exception()) - self._stm_tl_segment_prefix_if_necessary(self.mc) + self._tl_segment_if_stm(self.mc) self.mc.MOV(loc1, heap(ea)) self.mc.CMP(loc1, loc) self.implement_guard(guard_token, 'NE') @@ -1838,7 +1821,7 @@ eva = self._get_stm_tl(self.cpu.pos_exc_value()) ea = self._get_stm_tl(self.cpu.pos_exception()) # - self._stm_tl_segment_prefix_if_necessary(mc) + self._tl_segment_if_stm(mc) if excvalloc is not None: assert excvalloc.is_core_reg() mc.MOV(excvalloc, heap(eva)) @@ -1849,28 +1832,28 @@ # if exctploc is not None: assert exctploc.is_core_reg() - self._stm_tl_segment_prefix_if_necessary(mc) + self._tl_segment_if_stm(mc) mc.MOV(exctploc, heap(ea)) # - self._stm_tl_segment_prefix_if_necessary(mc) + self._tl_segment_if_stm(mc) mc.MOV(heap(ea), imm0) - self._stm_tl_segment_prefix_if_necessary(mc) + self._tl_segment_if_stm(mc) mc.MOV(heap(eva), imm0) def _restore_exception(self, mc, excvalloc, exctploc, tmploc=None): eva = self._get_stm_tl(self.cpu.pos_exc_value()) ea = self._get_stm_tl(self.cpu.pos_exception()) if excvalloc is not None: - self._stm_tl_segment_prefix_if_necessary(mc) + self._tl_segment_if_stm(mc) mc.MOV(heap(eva), excvalloc) else: assert tmploc is not None ofs = self.cpu.get_ofs_of_frame_field('jf_guard_exc') mc.MOV(tmploc, RawEbpLoc(ofs)) mc.MOV_bi(ofs, 0) - self._stm_tl_segment_prefix_if_necessary(mc) + self._tl_segment_if_stm(mc) mc.MOV(heap(eva), tmploc) - self._stm_tl_segment_prefix_if_necessary(mc) + self._tl_segment_if_stm(mc) mc.MOV(heap(ea), exctploc) def _gen_guard_overflow(self, guard_op, guard_token): @@ -2072,11 +2055,11 @@ # We might have an exception pending. Load it into ebx... eva = self._get_stm_tl(self.cpu.pos_exc_value()) ea = self._get_stm_tl(self.cpu.pos_exception()) - self._stm_tl_segment_prefix_if_necessary(mc) + self._tl_segment_if_stm(mc) mc.MOV(ebx, heap(eva)) - self._stm_tl_segment_prefix_if_necessary(mc) + self._tl_segment_if_stm(mc) mc.MOV(heap(ea), imm0) - self._stm_tl_segment_prefix_if_necessary(mc) + self._tl_segment_if_stm(mc) mc.MOV(heap(eva), imm0) # ...and save ebx into 'jf_guard_exc' offset = self.cpu.get_ofs_of_frame_field('jf_guard_exc') @@ -2394,24 +2377,14 @@ mc.overwrite(j_ok3 - 1, chr(offset)) def _get_stm_private_rev_num_addr(self): - assert self.cpu.gc_ll_descr.stm - rn = rstm.get_adr_of_private_rev_num() - rn = rn - stmtlocal.threadlocal_base() - assert rx86.fits_in_32bits(rn) - return rn + return self._get_stm_tl(rstm.get_adr_of_private_rev_num()) def _get_stm_read_barrier_cache_addr(self): - assert self.cpu.gc_ll_descr.stm - rbc = rstm.get_adr_of_read_barrier_cache() - rbc = rbc - stmtlocal.threadlocal_base() - assert rx86.fits_in_32bits(rbc) - return rbc + return self._get_stm_tl(rstm.get_adr_of_read_barrier_cache()) def _stm_barrier_fastpath(self, mc, descr, arglocs, is_frame=False, align_stack=False): assert self.cpu.gc_ll_descr.stm - from rpython.jit.backend.llsupport.gc import ( - STMBarrierDescr, STMReadBarrierDescr, STMWriteBarrierDescr) if we_are_translated(): # tests use a a mock class, but translation needs it assert isinstance(descr, STMBarrierDescr) @@ -2442,7 +2415,7 @@ if we_are_translated(): # during tests, _get_stm_private_rev_num_addr returns # an absolute address, not a tl-offset - stmtlocal.tl_segment_prefix(mc) + self._tl_segment_if_stm(mc) mc.MOV_rj(X86_64_SCRATCH_REG.value, rn) else: # testing: mc.MOV(X86_64_SCRATCH_REG, heap(rn)) @@ -2472,7 +2445,7 @@ if we_are_translated(): # during tests, _get_stm_rbca returns # an absolute address, not a tl-offset - stmtlocal.tl_segment_prefix(mc) + self._tl_segment_if_stm(mc) mc.ADD_rj(X86_64_SCRATCH_REG.value, rbc) else: # testing: mc.PUSH_r(eax.value) diff --git a/rpython/jit/backend/x86/test/test_stm_integration.py b/rpython/jit/backend/x86/test/test_stm_integration.py --- a/rpython/jit/backend/x86/test/test_stm_integration.py +++ b/rpython/jit/backend/x86/test/test_stm_integration.py @@ -531,7 +531,9 @@ ResOperation(rop.FINISH, [i], None, descr=finaldescr) ) + print operations + # COMPILE & EXECUTE LOOP: inputargs = [p for p in (p1, p2) if not isinstance(p, Const)] @@ -541,9 +543,6 @@ args = [s for i, s in enumerate((s1, s2)) if not isinstance((p1, p2)[i], Const)] + [7] - print "======" - print "inputargs:", inputargs+[i1], args - print "\n".join(map(str,c_loop[1])) frame = self.cpu.execute_token(looptoken, *args) frame = rffi.cast(JITFRAMEPTR, frame) @@ -692,9 +691,6 @@ looptoken) args = [] - print "======" - print "inputargs:", inputargs, args - print "\n".join(map(str,c_loop[1])) frame = self.cpu.execute_token(looptoken, *args) @@ -742,7 +738,6 @@ looptoken = JitCellToken() looptoken.outermost_jitdriver_sd = FakeJitDriverSD() c_loop = cpu.compile_loop(None, inputargs, ops, looptoken) - print "\n".join(map(str,c_loop[1])) ARGS = [lltype.Signed] * 10 RES = lltype.Signed @@ -766,7 +761,6 @@ othertoken = JitCellToken() cpu.done_with_this_frame_descr_int = BasicFinalDescr() c_loop = cpu.compile_loop(None, [], ops, othertoken) - print "\n".join(map(str,c_loop[1])) deadframe = cpu.execute_token(othertoken) frame = rffi.cast(JITFRAMEPTR, deadframe) From noreply at buildbot.pypy.org Sat Sep 7 16:26:05 2013 From: noreply at buildbot.pypy.org (bivab) Date: Sat, 7 Sep 2013 16:26:05 +0200 (CEST) Subject: [pypy-commit] pypy default: these should be lists and not tuples containing a list Message-ID: <20130907142605.97FE21C02A7@cobra.cs.uni-duesseldorf.de> Author: David Schneider Branch: Changeset: r66829:d42adaf4a4c1 Date: 2013-09-07 16:24 +0200 http://bitbucket.org/pypy/pypy/changeset/d42adaf4a4c1/ Log: these should be lists and not tuples containing a list diff --git a/lib_pypy/_tkinter/tklib.py b/lib_pypy/_tkinter/tklib.py --- a/lib_pypy/_tkinter/tklib.py +++ b/lib_pypy/_tkinter/tklib.py @@ -110,8 +110,8 @@ linklibs = ['tk85', 'tcl85'] libdirs = ['/usr/local/lib', '/usr/X11R6/lib'] else: - incdirs=['/usr/include/tcl'], - linklibs=['tcl', 'tk'], + incdirs=['/usr/include/tcl'] + linklibs=['tcl', 'tk'] libdirs = [] tklib = tkffi.verify(""" From noreply at buildbot.pypy.org Sat Sep 7 16:26:06 2013 From: noreply at buildbot.pypy.org (bivab) Date: Sat, 7 Sep 2013 16:26:06 +0200 (CEST) Subject: [pypy-commit] pypy default: merge heads Message-ID: <20130907142606.D65D21C02A7@cobra.cs.uni-duesseldorf.de> Author: David Schneider Branch: Changeset: r66830:9c7efdd6a360 Date: 2013-09-07 16:24 +0200 http://bitbucket.org/pypy/pypy/changeset/9c7efdd6a360/ Log: merge heads 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 @@ -26,6 +26,9 @@ def try_ldflags(): yield ExternalCompilationInfo(libraries=['curses']) yield ExternalCompilationInfo(libraries=['curses', 'tinfo']) + yield ExternalCompilationInfo(libraries=['ncurses']) + yield ExternalCompilationInfo(libraries=['ncurses'], + library_dirs=['/usr/lib64']) def try_tools(): try: diff --git a/rpython/rtyper/test/test_rclass.py b/rpython/rtyper/test/test_rclass.py --- a/rpython/rtyper/test/test_rclass.py +++ b/rpython/rtyper/test/test_rclass.py @@ -1192,3 +1192,19 @@ assert self.interpret(f, [True]) == f(True) assert self.interpret(f, [False]) == f(False) + + def test_init_with_star_args(self): + class Base(object): + def __init__(self, a, b): + self.a = a + self.b = b + class A(Base): + def __init__(self, *args): + Base.__init__(self, *args) + self.c = -1 + cls = [Base, A] + + def f(k, a, b): + return cls[k](a, b).b + + assert self.interpret(f, [1, 4, 7]) == 7 From noreply at buildbot.pypy.org Sat Sep 7 18:12:26 2013 From: noreply at buildbot.pypy.org (arigo) Date: Sat, 7 Sep 2013 18:12:26 +0200 (CEST) Subject: [pypy-commit] stmgc default: Add a passing test for stm_clear_on_abort() Message-ID: <20130907161226.B2B8F1C0112@cobra.cs.uni-duesseldorf.de> Author: Armin Rigo Branch: Changeset: r522:a8273b98ef59 Date: 2013-09-07 16:42 +0200 http://bitbucket.org/pypy/stmgc/changeset/a8273b98ef59/ Log: Add a passing test for stm_clear_on_abort() diff --git a/c4/test/support.py b/c4/test/support.py --- a/c4/test/support.py +++ b/c4/test/support.py @@ -127,6 +127,8 @@ void stm_initialize_and_set_max_abort(int max_aborts); void stm_initialize_tests(int max_aborts); + void stm_clear_on_abort(void *start, size_t bytes); + /* some constants normally private that are useful in the tests */ #define WORD ... #define GC_PAGE_SIZE ... diff --git a/c4/test/test_extra.py b/c4/test/test_extra.py --- a/c4/test/test_extra.py +++ b/c4/test/test_extra.py @@ -253,5 +253,19 @@ check_free_old(p3o) check_free_old(p2) - - + +def test_clear_on_abort(): + p = ffi.new("char[]", "hello") + lib.stm_clear_on_abort(p, 2) + # + @perform_transaction + def run(retry_counter): + if retry_counter == 0: + assert ffi.string(p) == "hello" + abort_and_retry() + else: + assert p[0] == '\0' + assert p[1] == '\0' + assert p[2] == 'l' + assert p[3] == 'l' + assert p[4] == 'o' From noreply at buildbot.pypy.org Sat Sep 7 18:12:27 2013 From: noreply at buildbot.pypy.org (arigo) Date: Sat, 7 Sep 2013 18:12:27 +0200 (CEST) Subject: [pypy-commit] stmgc default: stm_clear_on_abort(): move the thread-local variables into the Message-ID: <20130907161227.E333B1C0112@cobra.cs.uni-duesseldorf.de> Author: Armin Rigo Branch: Changeset: r523:4c80cba2b8ce Date: 2013-09-07 17:19 +0200 http://bitbucket.org/pypy/stmgc/changeset/4c80cba2b8ce/ Log: stm_clear_on_abort(): move the thread-local variables into the tx_descriptor structure. Add stm_call_on_abort() for invoking callbacks (like free()) if the current transaction is aborted. diff --git a/c4/et.c b/c4/et.c --- a/c4/et.c +++ b/c4/et.c @@ -986,8 +986,12 @@ spinlock_release(d->public_descriptor->collection_lock); /* clear memory registered by stm_clear_on_abort */ - if (stm_to_clear_on_abort) - memset(stm_to_clear_on_abort, 0, stm_bytes_to_clear_on_abort); + if (d->mem_clear_on_abort) + memset(d->mem_clear_on_abort, 0, d->mem_bytes_to_clear_on_abort); + + /* invoke the callbacks registered by stm_call_on_abort */ + stm_invoke_callbacks_on_abort(d); + stm_clear_callbacks_on_abort(d); dprintf(("\n" "!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!\n" @@ -1482,6 +1486,10 @@ d->num_commits++; d->active = 0; stm_stop_sharedlock(); + + /* clear the list of callbacks that would have been called + on abort */ + stm_clear_callbacks_on_abort(d); } /************************************************************/ diff --git a/c4/et.h b/c4/et.h --- a/c4/et.h +++ b/c4/et.h @@ -183,6 +183,9 @@ struct tx_descriptor *tx_prev, *tx_next; int tcolor; pthread_t pthreadid; + void *mem_clear_on_abort; + size_t mem_bytes_to_clear_on_abort; + struct G2L callbacks_on_abort; }; extern __thread struct tx_descriptor *thread_descriptor; diff --git a/c4/extra.c b/c4/extra.c --- a/c4/extra.c +++ b/c4/extra.c @@ -14,13 +14,46 @@ } -__thread void *stm_to_clear_on_abort = NULL; -__thread size_t stm_bytes_to_clear_on_abort; - void stm_clear_on_abort(void *start, size_t bytes) { - stm_to_clear_on_abort = start; - stm_bytes_to_clear_on_abort = bytes; + struct tx_descriptor *d = thread_descriptor; + assert(d != NULL); + d->mem_clear_on_abort = start; + d->mem_bytes_to_clear_on_abort = bytes; +} + +void stm_call_on_abort(void *key, void callback(void *)) +{ + struct tx_descriptor *d = thread_descriptor; + if (callback == NULL) { + /* ignore the return value: unregistered keys can be + "deleted" again */ + g2l_delete_item(&d->callbacks_on_abort, (gcptr)key); + } + else { + /* double-registering the same key will crash */ + g2l_insert(&d->callbacks_on_abort, (gcptr)key, (gcptr)callback); + } +} + +void stm_clear_callbacks_on_abort(struct tx_descriptor *d) +{ + if (g2l_any_entry(&d->callbacks_on_abort)) + g2l_clear(&d->callbacks_on_abort); +} + +void stm_invoke_callbacks_on_abort(struct tx_descriptor *d) +{ + wlog_t *item; + G2L_LOOP_FORWARD(d->callbacks_on_abort, item) { + void *key = (void *)item->addr; + void (*callback)(void *) = (void(*)(void *))item->val; + assert(key != NULL); + assert(callback != NULL); + + callback(key); + + } G2L_LOOP_END; } diff --git a/c4/extra.h b/c4/extra.h --- a/c4/extra.h +++ b/c4/extra.h @@ -17,5 +17,7 @@ size_t stm_decode_abort_info(struct tx_descriptor *d, long long elapsed_time, int abort_reason, struct tx_abort_info *output); void stm_visit_abort_info(struct tx_descriptor *d, void (*visit)(gcptr *)); +void stm_clear_callbacks_on_abort(struct tx_descriptor *d); +void stm_invoke_callbacks_on_abort(struct tx_descriptor *d); #endif diff --git a/c4/gcpage.c b/c4/gcpage.c --- a/c4/gcpage.c +++ b/c4/gcpage.c @@ -207,7 +207,8 @@ //stm_dbgmem_not_used(obj, size_class * WORD, 0); } else { - g2l_delete_item(&gcp->nonsmall_objects, obj); + int deleted = g2l_delete_item(&gcp->nonsmall_objects, obj); + assert(deleted); stm_free(obj); } } @@ -234,7 +235,8 @@ assert(obj->h_tid & GCFLAG_PUBLIC); stmgcpage_acquire_global_lock(); - g2l_delete_item(®istered_stubs, obj); + int deleted = g2l_delete_item(®istered_stubs, obj); + assert(deleted); stmgcpage_release_global_lock(); dprintf(("unregistered %p\n", obj)); } diff --git a/c4/lists.c b/c4/lists.c --- a/c4/lists.c +++ b/c4/lists.c @@ -132,15 +132,15 @@ *(char **)p = (char *)wlog; } -void g2l_delete_item(struct G2L *g2l, gcptr addr) +int g2l_delete_item(struct G2L *g2l, gcptr addr) { wlog_t *entry; G2L_FIND(*g2l, addr, entry, goto missing); entry->addr = NULL; - return; + return 1; missing: - stm_fatalerror("g2l_delete_item: item %p not in dict", addr); + return 0; } /************************************************************/ diff --git a/c4/lists.h b/c4/lists.h --- a/c4/lists.h +++ b/c4/lists.h @@ -113,7 +113,7 @@ wlog_t *_g2l_find(char *entry, gcptr addr); void _g2l_compress(struct G2L *g2l); void g2l_insert(struct G2L *g2l, gcptr addr, gcptr val); -void g2l_delete_item(struct G2L *g2l, gcptr addr); +int g2l_delete_item(struct G2L *g2l, gcptr addr); static inline int g2l_contains(struct G2L *g2l, gcptr addr) { diff --git a/c4/stmgc.h b/c4/stmgc.h --- a/c4/stmgc.h +++ b/c4/stmgc.h @@ -175,10 +175,14 @@ /* Clear some memory when aborting a transaction in the current thread. This is a provisional API. The information is stored - thread-locally and belongs to the current thread. */ + in the current tx_descriptor. */ void stm_clear_on_abort(void *start, size_t bytes); -extern __thread void *stm_to_clear_on_abort; -extern __thread size_t stm_bytes_to_clear_on_abort; + +/* If the current transaction aborts later, invoke 'callback(key)'. + If the current transaction commits, then the callback is forgotten. + You can only register one callback per key. You can call + 'stm_call_on_abort(key, NULL)' to cancel an existing callback. */ +void stm_call_on_abort(void *key, void callback(void *)); /* only user currently is stm_allocate_public_integer_address() */ void stm_register_integer_address(intptr_t); diff --git a/c4/test/support.py b/c4/test/support.py --- a/c4/test/support.py +++ b/c4/test/support.py @@ -128,6 +128,7 @@ void stm_initialize_tests(int max_aborts); void stm_clear_on_abort(void *start, size_t bytes); + void stm_call_on_abort(void *key, void callback(void *)); /* some constants normally private that are useful in the tests */ #define WORD ... diff --git a/c4/test/test_extra.py b/c4/test/test_extra.py --- a/c4/test/test_extra.py +++ b/c4/test/test_extra.py @@ -269,3 +269,42 @@ assert p[2] == 'l' assert p[3] == 'l' assert p[4] == 'o' + +def test_call_on_abort(): + p0 = ffi.new("char[]", "aaa") + p1 = ffi.new("char[]", "hello") + p2 = ffi.new("char[]", "removed") + p3 = ffi.new("char[]", "world") + # + @ffi.callback("void(void *)") + def clear_me(p): + p = ffi.cast("char *", p) + p[0] = chr(ord(p[0]) + 1) + # + lib.stm_call_on_abort(p0, clear_me) + # the registered callbacks are removed on + # successful commit + lib.stm_commit_transaction() + lib.stm_begin_inevitable_transaction() + # + @perform_transaction + def run(retry_counter): + if retry_counter == 0: + lib.stm_call_on_abort(p1, clear_me) + lib.stm_call_on_abort(p2, clear_me) + lib.stm_call_on_abort(p3, clear_me) + lib.stm_call_on_abort(p2, ffi.NULL) + # + assert ffi.string(p0) == "aaa" + assert ffi.string(p2) == "removed" + if retry_counter == 0: + assert ffi.string(p1) == "hello" + assert ffi.string(p3) == "world" + abort_and_retry() + else: + assert ffi.string(p1) == "iello" + assert ffi.string(p3) == "xorld" + if retry_counter == 1: + # the registered callbacks are removed + # on abort + abort_and_retry() From noreply at buildbot.pypy.org Sat Sep 7 18:15:50 2013 From: noreply at buildbot.pypy.org (arigo) Date: Sat, 7 Sep 2013 18:15:50 +0200 (CEST) Subject: [pypy-commit] pypy stmgc-c4: This may fix the order dependency. Message-ID: <20130907161550.B1FD11C0112@cobra.cs.uni-duesseldorf.de> Author: Armin Rigo Branch: stmgc-c4 Changeset: r66831:6fc66b2d62d4 Date: 2013-09-07 14:41 +0200 http://bitbucket.org/pypy/pypy/changeset/6fc66b2d62d4/ Log: This may fix the order dependency. diff --git a/rpython/translator/stm/writebarrier.py b/rpython/translator/stm/writebarrier.py --- a/rpython/translator/stm/writebarrier.py +++ b/rpython/translator/stm/writebarrier.py @@ -54,9 +54,12 @@ self.stmtransformer = stmtransformer self.block = block self.patch = None - self.inputargs_category = [None] * len(block.inputargs) + self.inputargs_category = None self.inputargs_category_per_link = {} + def init_start_block(self): + self.inputargs_category = [None] * len(self.block.inputargs) + def analyze_inside_block(self): gcremovetypeptr = ( @@ -351,7 +354,6 @@ insert_empty_startblock(annotator, graph) block_transformers = {} - pending = set() for block in graph.iterblocks(): if block.operations == (): @@ -359,14 +361,13 @@ bt = BlockTransformer(stmtransformer, block) bt.analyze_inside_block() block_transformers[block] = bt - pending.add(bt) + + bt = block_transformers[graph.startblock] + bt.init_start_block() + pending = set([bt]) while pending: - # XXX sadly, this seems to be order-dependent. Picking the minimum - # of the blocks seems to be necessary, too, to avoid the situation - # of two blocks chasing each other around a loop :-( - bt = min(pending) - pending.remove(bt) + bt = pending.pop() bt.flow_through_block(graphinfo) pending |= bt.update_targets(block_transformers) From noreply at buildbot.pypy.org Sat Sep 7 18:15:51 2013 From: noreply at buildbot.pypy.org (arigo) Date: Sat, 7 Sep 2013 18:15:51 +0200 (CEST) Subject: [pypy-commit] pypy stmgc-c4: Don't use None as category. This should ensure that all Message-ID: <20130907161551.CC2A41C0112@cobra.cs.uni-duesseldorf.de> Author: Armin Rigo Branch: stmgc-c4 Changeset: r66832:c41af7541a8a Date: 2013-09-07 14:50 +0200 http://bitbucket.org/pypy/pypy/changeset/c41af7541a8a/ Log: Don't use None as category. This should ensure that all categories are decreasing over time, eventually reaching a fixed point. diff --git a/rpython/translator/stm/writebarrier.py b/rpython/translator/stm/writebarrier.py --- a/rpython/translator/stm/writebarrier.py +++ b/rpython/translator/stm/writebarrier.py @@ -58,7 +58,9 @@ self.inputargs_category_per_link = {} def init_start_block(self): - self.inputargs_category = [None] * len(self.block.inputargs) + from_outside = ['A'] * len(self.block.inputargs) + self.inputargs_category_per_link[None] = from_outside + self.update_inputargs_category() def analyze_inside_block(self): @@ -164,7 +166,8 @@ # make the initial trivial renamings needed to have some precise # categories for the input args for v, cat in zip(self.block.inputargs, self.inputargs_category): - if cat is not None and is_gc_ptr(v.concretetype): + if is_gc_ptr(v.concretetype): + assert cat is not None renamings[v] = Renaming(v, cat) for op in self.block.operations: @@ -303,14 +306,10 @@ values = self.inputargs_category_per_link.values() newcats = [] for i in range(len(self.block.inputargs)): - cat = None - for output_categories in values: - cat2 = output_categories[i] - if cat is None: - cat = cat2 - elif cat2 is not None: - cat = min(cat, cat2) - newcats.append(cat) + cats = [output_categories[i] for output_categories in values] + if is_gc_ptr(self.block.inputargs[i]): + assert None not in cats + newcats.append(min(cats)) if newcats != self.inputargs_category: self.inputargs_category = newcats return True From noreply at buildbot.pypy.org Sat Sep 7 18:15:52 2013 From: noreply at buildbot.pypy.org (arigo) Date: Sat, 7 Sep 2013 18:15:52 +0200 (CEST) Subject: [pypy-commit] pypy stmgc-c4: Rewrite this part Message-ID: <20130907161552.EB45C1C0112@cobra.cs.uni-duesseldorf.de> Author: Armin Rigo Branch: stmgc-c4 Changeset: r66833:b691675f163c Date: 2013-09-07 16:16 +0200 http://bitbucket.org/pypy/pypy/changeset/b691675f163c/ Log: Rewrite this part diff --git a/rpython/translator/stm/writebarrier.py b/rpython/translator/stm/writebarrier.py --- a/rpython/translator/stm/writebarrier.py +++ b/rpython/translator/stm/writebarrier.py @@ -305,11 +305,13 @@ def update_inputargs_category(self): values = self.inputargs_category_per_link.values() newcats = [] - for i in range(len(self.block.inputargs)): - cats = [output_categories[i] for output_categories in values] - if is_gc_ptr(self.block.inputargs[i]): + for i, v in enumerate(self.block.inputargs): + if is_gc_ptr(v.concretetype): + cats = [output_categories[i] for output_categories in values] assert None not in cats - newcats.append(min(cats)) + newcats.append(min(cats)) + else: + newcats.append(None) if newcats != self.inputargs_category: self.inputargs_category = newcats return True From noreply at buildbot.pypy.org Sat Sep 7 18:15:54 2013 From: noreply at buildbot.pypy.org (arigo) Date: Sat, 7 Sep 2013 18:15:54 +0200 (CEST) Subject: [pypy-commit] pypy stmgc-c4: Remove clear_exception_data_on_abort() and piggy-back calls Message-ID: <20130907161554.125F01C0112@cobra.cs.uni-duesseldorf.de> Author: Armin Rigo Branch: stmgc-c4 Changeset: r66834:a8ad1e23eb92 Date: 2013-09-07 16:34 +0200 http://bitbucket.org/pypy/pypy/changeset/a8ad1e23eb92/ Log: Remove clear_exception_data_on_abort() and piggy-back calls to stm_clear_on_abort() to stm_initialize(). diff --git a/pypy/module/thread/stm.py b/pypy/module/thread/stm.py --- a/pypy/module/thread/stm.py +++ b/pypy/module/thread/stm.py @@ -18,7 +18,6 @@ def initialize_execution_context(ec): """Called from ExecutionContext.__init__().""" - rstm.clear_exception_data_on_abort() ec._thread_local_dicts = rweakref.RWeakKeyDictionary(STMLocal, W_Root) if ec.space.config.objspace.std.withmethodcache: from pypy.objspace.std.typeobject import MethodCache diff --git a/rpython/rlib/rstm.py b/rpython/rlib/rstm.py --- a/rpython/rlib/rstm.py +++ b/rpython/rlib/rstm.py @@ -15,25 +15,6 @@ return rffi.cast(lltype.Signed, addr) @dont_look_inside -def clear_exception_data_on_abort(): - # XXX: provisional API just to be safe - # called by pypy/module/thread/stm:initialize_execution_context - pass - -class ClearExceptionDataOnAbort(ExtRegistryEntry): - _about_ = clear_exception_data_on_abort - - 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() - return hop.genop('stm_clear_exception_data_on_abort', [], - resulttype=lltype.Void) - - - at dont_look_inside def become_inevitable(): llop.stm_become_inevitable(lltype.Void) diff --git a/rpython/rtyper/llinterp.py b/rpython/rtyper/llinterp.py --- a/rpython/rtyper/llinterp.py +++ b/rpython/rtyper/llinterp.py @@ -974,7 +974,6 @@ op_stm_major_collect = _stm_not_implemented op_stm_abort_and_retry = _stm_not_implemented op_stm_become_inevitable = _stm_not_implemented - op_stm_clear_exception_data_on_abort = _stm_not_implemented # __________________________________________________________ # operations on addresses 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 @@ -449,8 +449,6 @@ 'stm_get_adr_of_private_rev_num':LLOp(), 'stm_get_adr_of_read_barrier_cache':LLOp(), - 'stm_clear_exception_data_on_abort':LLOp(), - # __________ address operations __________ 'boehm_malloc': LLOp(), diff --git a/rpython/translator/stm/funcgen.py b/rpython/translator/stm/funcgen.py --- a/rpython/translator/stm/funcgen.py +++ b/rpython/translator/stm/funcgen.py @@ -43,7 +43,10 @@ def stm_initialize(funcgen, op): - return 'stm_initialize();' + return '''stm_initialize(); + stm_clear_on_abort(&pypy_g_ExcData.ed_exc_type, + sizeof(struct pypy_object0 *)); + ''' def stm_finalize(funcgen, op): return 'stm_finalize();' @@ -227,13 +230,6 @@ def stm_major_collect(funcgen, op): return 'stm_major_collect();' -def stm_clear_exception_data_on_abort(funcgen, op): - return """ - stm_clear_on_abort(&pypy_g_ExcData.ed_exc_type, - sizeof(struct pypy_object0 *)); - """ - - def op_stm(funcgen, op): func = globals()[op.opname] From noreply at buildbot.pypy.org Sat Sep 7 18:15:55 2013 From: noreply at buildbot.pypy.org (arigo) Date: Sat, 7 Sep 2013 18:15:55 +0200 (CEST) Subject: [pypy-commit] pypy stmgc-c4: Import stmgc/4c80cba2b8ce Message-ID: <20130907161555.402301C0112@cobra.cs.uni-duesseldorf.de> Author: Armin Rigo Branch: stmgc-c4 Changeset: r66835:157e0dd6ad13 Date: 2013-09-07 18:12 +0200 http://bitbucket.org/pypy/pypy/changeset/157e0dd6ad13/ Log: Import stmgc/4c80cba2b8ce diff --git a/rpython/translator/stm/src_stm/et.c b/rpython/translator/stm/src_stm/et.c --- a/rpython/translator/stm/src_stm/et.c +++ b/rpython/translator/stm/src_stm/et.c @@ -987,8 +987,12 @@ spinlock_release(d->public_descriptor->collection_lock); /* clear memory registered by stm_clear_on_abort */ - if (stm_to_clear_on_abort) - memset(stm_to_clear_on_abort, 0, stm_bytes_to_clear_on_abort); + if (d->mem_clear_on_abort) + memset(d->mem_clear_on_abort, 0, d->mem_bytes_to_clear_on_abort); + + /* invoke the callbacks registered by stm_call_on_abort */ + stm_invoke_callbacks_on_abort(d); + stm_clear_callbacks_on_abort(d); dprintf(("\n" "!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!\n" @@ -1483,6 +1487,10 @@ d->num_commits++; d->active = 0; stm_stop_sharedlock(); + + /* clear the list of callbacks that would have been called + on abort */ + stm_clear_callbacks_on_abort(d); } /************************************************************/ 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 @@ -184,6 +184,9 @@ struct tx_descriptor *tx_prev, *tx_next; int tcolor; pthread_t pthreadid; + void *mem_clear_on_abort; + size_t mem_bytes_to_clear_on_abort; + struct G2L callbacks_on_abort; }; extern __thread struct tx_descriptor *thread_descriptor; diff --git a/rpython/translator/stm/src_stm/extra.c b/rpython/translator/stm/src_stm/extra.c --- a/rpython/translator/stm/src_stm/extra.c +++ b/rpython/translator/stm/src_stm/extra.c @@ -15,13 +15,46 @@ } -__thread void *stm_to_clear_on_abort = NULL; -__thread size_t stm_bytes_to_clear_on_abort; - void stm_clear_on_abort(void *start, size_t bytes) { - stm_to_clear_on_abort = start; - stm_bytes_to_clear_on_abort = bytes; + struct tx_descriptor *d = thread_descriptor; + assert(d != NULL); + d->mem_clear_on_abort = start; + d->mem_bytes_to_clear_on_abort = bytes; +} + +void stm_call_on_abort(void *key, void callback(void *)) +{ + struct tx_descriptor *d = thread_descriptor; + if (callback == NULL) { + /* ignore the return value: unregistered keys can be + "deleted" again */ + g2l_delete_item(&d->callbacks_on_abort, (gcptr)key); + } + else { + /* double-registering the same key will crash */ + g2l_insert(&d->callbacks_on_abort, (gcptr)key, (gcptr)callback); + } +} + +void stm_clear_callbacks_on_abort(struct tx_descriptor *d) +{ + if (g2l_any_entry(&d->callbacks_on_abort)) + g2l_clear(&d->callbacks_on_abort); +} + +void stm_invoke_callbacks_on_abort(struct tx_descriptor *d) +{ + wlog_t *item; + G2L_LOOP_FORWARD(d->callbacks_on_abort, item) { + void *key = (void *)item->addr; + void (*callback)(void *) = (void(*)(void *))item->val; + assert(key != NULL); + assert(callback != NULL); + + callback(key); + + } G2L_LOOP_END; } diff --git a/rpython/translator/stm/src_stm/extra.h b/rpython/translator/stm/src_stm/extra.h --- a/rpython/translator/stm/src_stm/extra.h +++ b/rpython/translator/stm/src_stm/extra.h @@ -18,5 +18,7 @@ size_t stm_decode_abort_info(struct tx_descriptor *d, long long elapsed_time, int abort_reason, struct tx_abort_info *output); void stm_visit_abort_info(struct tx_descriptor *d, void (*visit)(gcptr *)); +void stm_clear_callbacks_on_abort(struct tx_descriptor *d); +void stm_invoke_callbacks_on_abort(struct tx_descriptor *d); #endif diff --git a/rpython/translator/stm/src_stm/gcpage.c b/rpython/translator/stm/src_stm/gcpage.c --- a/rpython/translator/stm/src_stm/gcpage.c +++ b/rpython/translator/stm/src_stm/gcpage.c @@ -208,7 +208,8 @@ //stm_dbgmem_not_used(obj, size_class * WORD, 0); } else { - g2l_delete_item(&gcp->nonsmall_objects, obj); + int deleted = g2l_delete_item(&gcp->nonsmall_objects, obj); + assert(deleted); stm_free(obj); } } @@ -235,7 +236,8 @@ assert(obj->h_tid & GCFLAG_PUBLIC); stmgcpage_acquire_global_lock(); - g2l_delete_item(®istered_stubs, obj); + int deleted = g2l_delete_item(®istered_stubs, obj); + assert(deleted); stmgcpage_release_global_lock(); dprintf(("unregistered %p\n", obj)); } diff --git a/rpython/translator/stm/src_stm/lists.c b/rpython/translator/stm/src_stm/lists.c --- a/rpython/translator/stm/src_stm/lists.c +++ b/rpython/translator/stm/src_stm/lists.c @@ -133,15 +133,15 @@ *(char **)p = (char *)wlog; } -void g2l_delete_item(struct G2L *g2l, gcptr addr) +int g2l_delete_item(struct G2L *g2l, gcptr addr) { wlog_t *entry; G2L_FIND(*g2l, addr, entry, goto missing); entry->addr = NULL; - return; + return 1; missing: - stm_fatalerror("g2l_delete_item: item %p not in dict", addr); + return 0; } /************************************************************/ diff --git a/rpython/translator/stm/src_stm/lists.h b/rpython/translator/stm/src_stm/lists.h --- a/rpython/translator/stm/src_stm/lists.h +++ b/rpython/translator/stm/src_stm/lists.h @@ -114,7 +114,7 @@ wlog_t *_g2l_find(char *entry, gcptr addr); void _g2l_compress(struct G2L *g2l); void g2l_insert(struct G2L *g2l, gcptr addr, gcptr val); -void g2l_delete_item(struct G2L *g2l, gcptr addr); +int g2l_delete_item(struct G2L *g2l, gcptr addr); static inline int g2l_contains(struct G2L *g2l, gcptr addr) { diff --git a/rpython/translator/stm/src_stm/revision b/rpython/translator/stm/src_stm/revision --- a/rpython/translator/stm/src_stm/revision +++ b/rpython/translator/stm/src_stm/revision @@ -1,1 +1,1 @@ -24b6be3aaa67 +4c80cba2b8ce diff --git a/rpython/translator/stm/src_stm/stmgc.h b/rpython/translator/stm/src_stm/stmgc.h --- a/rpython/translator/stm/src_stm/stmgc.h +++ b/rpython/translator/stm/src_stm/stmgc.h @@ -176,10 +176,14 @@ /* Clear some memory when aborting a transaction in the current thread. This is a provisional API. The information is stored - thread-locally and belongs to the current thread. */ + in the current tx_descriptor. */ void stm_clear_on_abort(void *start, size_t bytes); -extern __thread void *stm_to_clear_on_abort; -extern __thread size_t stm_bytes_to_clear_on_abort; + +/* If the current transaction aborts later, invoke 'callback(key)'. + If the current transaction commits, then the callback is forgotten. + You can only register one callback per key. You can call + 'stm_call_on_abort(key, NULL)' to cancel an existing callback. */ +void stm_call_on_abort(void *key, void callback(void *)); /* only user currently is stm_allocate_public_integer_address() */ void stm_register_integer_address(intptr_t); From noreply at buildbot.pypy.org Sat Sep 7 18:15:56 2013 From: noreply at buildbot.pypy.org (arigo) Date: Sat, 7 Sep 2013 18:15:56 +0200 (CEST) Subject: [pypy-commit] pypy stmgc-c4: merge heads Message-ID: <20130907161556.9BE171C0112@cobra.cs.uni-duesseldorf.de> Author: Armin Rigo Branch: stmgc-c4 Changeset: r66836:17f62ee163f2 Date: 2013-09-07 18:14 +0200 http://bitbucket.org/pypy/pypy/changeset/17f62ee163f2/ Log: merge heads diff --git a/lib_pypy/_tkinter/tklib.py b/lib_pypy/_tkinter/tklib.py --- a/lib_pypy/_tkinter/tklib.py +++ b/lib_pypy/_tkinter/tklib.py @@ -1,6 +1,7 @@ # C bindings with libtcl and libtk. from cffi import FFI +import sys tkffi = FFI() @@ -102,6 +103,17 @@ int Tk_GetNumMainWindows(); """) +# XXX find a better way to detect paths +# XXX pick up CPPFLAGS and LDFLAGS and add to these paths? +if sys.platform.startswith("openbsd"): + incdirs = ['/usr/local/include/tcl8.5', '/usr/local/include/tk8.5', '/usr/X11R6/include'] + linklibs = ['tk85', 'tcl85'] + libdirs = ['/usr/local/lib', '/usr/X11R6/lib'] +else: + incdirs=['/usr/include/tcl'], + linklibs=['tcl', 'tk'], + libdirs = [] + tklib = tkffi.verify(""" #include #include @@ -109,6 +121,7 @@ char *get_tk_version() { return TK_VERSION; } char *get_tcl_version() { return TCL_VERSION; } """, -include_dirs=['/usr/include/tcl'], -libraries=['tcl', 'tk'], +include_dirs=incdirs, +libraries=linklibs, +library_dirs = libdirs ) diff --git a/pypy/interpreter/baseobjspace.py b/pypy/interpreter/baseobjspace.py --- a/pypy/interpreter/baseobjspace.py +++ b/pypy/interpreter/baseobjspace.py @@ -77,12 +77,12 @@ raise NotImplementedError("only for interp-level user subclasses " "from typedef.py") - def getname(self, space, default='?'): + def getname(self, space): try: return space.str_w(space.getattr(self, space.wrap('__name__'))) except OperationError, e: if e.match(space, space.w_TypeError) or e.match(space, space.w_AttributeError): - return default + return '?' raise def getaddrstring(self, space): diff --git a/pypy/interpreter/function.py b/pypy/interpreter/function.py --- a/pypy/interpreter/function.py +++ b/pypy/interpreter/function.py @@ -482,17 +482,16 @@ space.abstract_isinstance_w(w_firstarg, self.w_class)): pass # ok else: - clsdescr = self.w_class.getname(space, "") - if clsdescr: + clsdescr = self.w_class.getname(space) + if clsdescr and clsdescr != '?': clsdescr += " instance" else: clsdescr = "instance" if w_firstarg is None: instdescr = "nothing" else: - instname = space.abstract_getclass(w_firstarg).getname(space, - "") - if instname: + instname = space.abstract_getclass(w_firstarg).getname(space) + if instname and instname != '?': instdescr = instname + " instance" else: instdescr = "instance" diff --git a/pypy/interpreter/test/test_argument.py b/pypy/interpreter/test/test_argument.py --- a/pypy/interpreter/test/test_argument.py +++ b/pypy/interpreter/test/test_argument.py @@ -128,7 +128,7 @@ def type(self, obj): class Type: - def getname(self, space, default='?'): + def getname(self, space): return type(obj).__name__ return Type() 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 @@ -26,6 +26,9 @@ def try_ldflags(): yield ExternalCompilationInfo(libraries=['curses']) yield ExternalCompilationInfo(libraries=['curses', 'tinfo']) + yield ExternalCompilationInfo(libraries=['ncurses']) + yield ExternalCompilationInfo(libraries=['ncurses'], + library_dirs=['/usr/lib64']) def try_tools(): try: 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 @@ -175,8 +175,8 @@ state = '; dead' else: typename = space.type(w_obj).getname(space) - objname = w_obj.getname(space, '') - if objname: + objname = w_obj.getname(space) + if objname and objname != '?': state = "; to '%s' (%s)" % (typename, objname) else: state = "; to '%s'" % (typename,) diff --git a/pypy/objspace/descroperation.py b/pypy/objspace/descroperation.py --- a/pypy/objspace/descroperation.py +++ b/pypy/objspace/descroperation.py @@ -597,8 +597,8 @@ if num1 != num2: lt = num1 # if obj1 is a number, it is Lower Than obj2 else: - name1 = w_typ1.getname(space, "") - name2 = w_typ2.getname(space, "") + name1 = w_typ1.getname(space) + name2 = w_typ2.getname(space) if name1 != name2: lt = name1 < name2 else: 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 @@ -502,6 +502,12 @@ else: return w_self.name + def getname(w_self, space): + name = w_self.name + if name is None: + name = '?' + return name + def add_subclass(w_self, w_subclass): space = w_self.space if not space.config.translation.rweakref: 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 @@ -37,6 +37,7 @@ from rpython.jit.backend.x86 import stmtlocal from rpython.rlib import rstm from rpython.memory.gc.stmgc import StmGC +from rpython.jit.backend.llsupport.gc import STMBarrierDescr class Assembler386(BaseAssembler): @@ -301,13 +302,15 @@ Before using such a relative address, call self._stm_tl_segment_prefix_if_necessary.""" if self.cpu.gc_ll_descr.stm and we_are_translated(): - # also not during tests + # only for STM and not during tests result = adr - stmtlocal.threadlocal_base() assert rx86.fits_in_32bits(result) return result return adr - def _stm_tl_segment_prefix_if_necessary(self, mc): + def _tl_segment_if_stm(self, mc): + """Insert segment prefix for thread-local memory if we run + in STM and not during testing.""" if self.cpu.gc_ll_descr.stm and we_are_translated(): stmtlocal.tl_segment_prefix(mc) @@ -346,7 +349,7 @@ mc.ADD_ri(esp.value, WORD) # ea = self._get_stm_tl(self.cpu.pos_exception()) - self._stm_tl_segment_prefix_if_necessary(mc) + self._tl_segment_if_stm(mc) mc.MOV(eax, heap(ea)) mc.TEST_rr(eax.value, eax.value) mc.J_il8(rx86.Conditions['NZ'], 0) @@ -900,11 +903,9 @@ that gives the address of the stack top. If this integer doesn't fit in 32 bits, it will be loaded in r11. """ - rst = self._get_root_stack_top_addr() + rst = self._get_stm_tl(gcrootmap.get_root_stack_top_addr()) if rx86.fits_in_32bits(rst): - if gcrootmap.is_stm and we_are_translated(): - # during testing, it will be an absolute address - stmtlocal.tl_segment_prefix(mc) + self._tl_segment_if_stm(mc) mc.MOV_rj(ebx.value, rst) # MOV ebx, [rootstacktop] else: mc.MOV_ri(X86_64_SCRATCH_REG.value, rst) # MOV r11, rootstacktop @@ -932,9 +933,7 @@ self.mc.ADD_ri(ebx.value, WORD) if rx86.fits_in_32bits(rst): - if gcrootmap.is_stm and we_are_translated(): - # during testing, it will be an absolute address - stmtlocal.tl_segment_prefix(self.mc) + self._tl_segment_if_stm(self.mc) self.mc.MOV_jr(rst, ebx.value) # MOV [rootstacktop], ebx else: # The integer 'rst' doesn't fit in 32 bits, so we know that @@ -944,12 +943,9 @@ ebx.value) # MOV [r11], ebx def _call_footer_shadowstack(self, gcrootmap): - rst = self._get_root_stack_top_addr() - + rst = self._get_stm_tl(gcrootmap.get_root_stack_top_addr()) if rx86.fits_in_32bits(rst): - if gcrootmap.is_stm and we_are_translated(): - # during testing, it will be an absolute address - stmtlocal.tl_segment_prefix(self.mc) + self._tl_segment_if_stm(self.mc) self.mc.SUB_ji8(rst, WORD) # SUB [rootstacktop], WORD else: self.mc.MOV_ri(ebx.value, rst) # MOV ebx, rootstacktop @@ -1262,25 +1258,12 @@ cb = callbuilder.CallBuilder(self, fnloc, arglocs) cb.emit_no_collect() - def _get_root_stack_top_addr(self): - gcrootmap = self.cpu.gc_ll_descr.gcrootmap - - rst = gcrootmap.get_root_stack_top_addr() - if gcrootmap.is_stm and we_are_translated(): - # during testing, we return an absolute address - rst = rst - stmtlocal.threadlocal_base() - assert rx86.fits_in_32bits(rst) - return rst - def _reload_frame_if_necessary(self, mc, align_stack=False): gc_ll_descr = self.cpu.gc_ll_descr gcrootmap = gc_ll_descr.gcrootmap if gcrootmap and gcrootmap.is_shadow_stack: - rst = self._get_root_stack_top_addr() - - if gcrootmap.is_stm and we_are_translated(): - # during testing, it will be an absolute address - stmtlocal.tl_segment_prefix(mc) + rst = self._get_stm_tl(gcrootmap.get_root_stack_top_addr()) + self._tl_segment_if_stm(mc) mc.MOV(ecx, heap(rst)) mc.MOV(ebp, mem(ecx, -WORD)) # @@ -1809,7 +1792,7 @@ def genop_guard_guard_no_exception(self, ign_1, guard_op, guard_token, locs, ign_2): ea = self._get_stm_tl(self.cpu.pos_exception()) - self._stm_tl_segment_prefix_if_necessary(self.mc) + self._tl_segment_if_stm(self.mc) self.mc.CMP(heap(ea), imm0) self.implement_guard(guard_token, 'NZ') @@ -1824,7 +1807,7 @@ loc = locs[0] loc1 = locs[1] ea = self._get_stm_tl(self.cpu.pos_exception()) - self._stm_tl_segment_prefix_if_necessary(self.mc) + self._tl_segment_if_stm(self.mc) self.mc.MOV(loc1, heap(ea)) self.mc.CMP(loc1, loc) self.implement_guard(guard_token, 'NE') @@ -1838,7 +1821,7 @@ eva = self._get_stm_tl(self.cpu.pos_exc_value()) ea = self._get_stm_tl(self.cpu.pos_exception()) # - self._stm_tl_segment_prefix_if_necessary(mc) + self._tl_segment_if_stm(mc) if excvalloc is not None: assert excvalloc.is_core_reg() mc.MOV(excvalloc, heap(eva)) @@ -1849,28 +1832,28 @@ # if exctploc is not None: assert exctploc.is_core_reg() - self._stm_tl_segment_prefix_if_necessary(mc) + self._tl_segment_if_stm(mc) mc.MOV(exctploc, heap(ea)) # - self._stm_tl_segment_prefix_if_necessary(mc) + self._tl_segment_if_stm(mc) mc.MOV(heap(ea), imm0) - self._stm_tl_segment_prefix_if_necessary(mc) + self._tl_segment_if_stm(mc) mc.MOV(heap(eva), imm0) def _restore_exception(self, mc, excvalloc, exctploc, tmploc=None): eva = self._get_stm_tl(self.cpu.pos_exc_value()) ea = self._get_stm_tl(self.cpu.pos_exception()) if excvalloc is not None: - self._stm_tl_segment_prefix_if_necessary(mc) + self._tl_segment_if_stm(mc) mc.MOV(heap(eva), excvalloc) else: assert tmploc is not None ofs = self.cpu.get_ofs_of_frame_field('jf_guard_exc') mc.MOV(tmploc, RawEbpLoc(ofs)) mc.MOV_bi(ofs, 0) - self._stm_tl_segment_prefix_if_necessary(mc) + self._tl_segment_if_stm(mc) mc.MOV(heap(eva), tmploc) - self._stm_tl_segment_prefix_if_necessary(mc) + self._tl_segment_if_stm(mc) mc.MOV(heap(ea), exctploc) def _gen_guard_overflow(self, guard_op, guard_token): @@ -2072,11 +2055,11 @@ # We might have an exception pending. Load it into ebx... eva = self._get_stm_tl(self.cpu.pos_exc_value()) ea = self._get_stm_tl(self.cpu.pos_exception()) - self._stm_tl_segment_prefix_if_necessary(mc) + self._tl_segment_if_stm(mc) mc.MOV(ebx, heap(eva)) - self._stm_tl_segment_prefix_if_necessary(mc) + self._tl_segment_if_stm(mc) mc.MOV(heap(ea), imm0) - self._stm_tl_segment_prefix_if_necessary(mc) + self._tl_segment_if_stm(mc) mc.MOV(heap(eva), imm0) # ...and save ebx into 'jf_guard_exc' offset = self.cpu.get_ofs_of_frame_field('jf_guard_exc') @@ -2394,24 +2377,14 @@ mc.overwrite(j_ok3 - 1, chr(offset)) def _get_stm_private_rev_num_addr(self): - assert self.cpu.gc_ll_descr.stm - rn = rstm.get_adr_of_private_rev_num() - rn = rn - stmtlocal.threadlocal_base() - assert rx86.fits_in_32bits(rn) - return rn + return self._get_stm_tl(rstm.get_adr_of_private_rev_num()) def _get_stm_read_barrier_cache_addr(self): - assert self.cpu.gc_ll_descr.stm - rbc = rstm.get_adr_of_read_barrier_cache() - rbc = rbc - stmtlocal.threadlocal_base() - assert rx86.fits_in_32bits(rbc) - return rbc + return self._get_stm_tl(rstm.get_adr_of_read_barrier_cache()) def _stm_barrier_fastpath(self, mc, descr, arglocs, is_frame=False, align_stack=False): assert self.cpu.gc_ll_descr.stm - from rpython.jit.backend.llsupport.gc import ( - STMBarrierDescr, STMReadBarrierDescr, STMWriteBarrierDescr) if we_are_translated(): # tests use a a mock class, but translation needs it assert isinstance(descr, STMBarrierDescr) @@ -2442,7 +2415,7 @@ if we_are_translated(): # during tests, _get_stm_private_rev_num_addr returns # an absolute address, not a tl-offset - stmtlocal.tl_segment_prefix(mc) + self._tl_segment_if_stm(mc) mc.MOV_rj(X86_64_SCRATCH_REG.value, rn) else: # testing: mc.MOV(X86_64_SCRATCH_REG, heap(rn)) @@ -2472,7 +2445,7 @@ if we_are_translated(): # during tests, _get_stm_rbca returns # an absolute address, not a tl-offset - stmtlocal.tl_segment_prefix(mc) + self._tl_segment_if_stm(mc) mc.ADD_rj(X86_64_SCRATCH_REG.value, rbc) else: # testing: mc.PUSH_r(eax.value) 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 @@ -28,6 +28,7 @@ from rpython.rlib.rarithmetic import r_longlong, r_uint from rpython.rtyper.lltypesystem.lloperation import llop from rpython.rtyper.lltypesystem import lltype, rffi, rstr +from rpython.rtyper.lltypesystem.lloperation import llop class X86RegisterManager(RegisterManager): diff --git a/rpython/jit/backend/x86/test/test_stm_integration.py b/rpython/jit/backend/x86/test/test_stm_integration.py --- a/rpython/jit/backend/x86/test/test_stm_integration.py +++ b/rpython/jit/backend/x86/test/test_stm_integration.py @@ -531,7 +531,9 @@ ResOperation(rop.FINISH, [i], None, descr=finaldescr) ) + print operations + # COMPILE & EXECUTE LOOP: inputargs = [p for p in (p1, p2) if not isinstance(p, Const)] @@ -541,9 +543,6 @@ args = [s for i, s in enumerate((s1, s2)) if not isinstance((p1, p2)[i], Const)] + [7] - print "======" - print "inputargs:", inputargs+[i1], args - print "\n".join(map(str,c_loop[1])) frame = self.cpu.execute_token(looptoken, *args) frame = rffi.cast(JITFRAMEPTR, frame) @@ -692,9 +691,6 @@ looptoken) args = [] - print "======" - print "inputargs:", inputargs, args - print "\n".join(map(str,c_loop[1])) frame = self.cpu.execute_token(looptoken, *args) @@ -742,7 +738,6 @@ looptoken = JitCellToken() looptoken.outermost_jitdriver_sd = FakeJitDriverSD() c_loop = cpu.compile_loop(None, inputargs, ops, looptoken) - print "\n".join(map(str,c_loop[1])) ARGS = [lltype.Signed] * 10 RES = lltype.Signed @@ -766,7 +761,6 @@ othertoken = JitCellToken() cpu.done_with_this_frame_descr_int = BasicFinalDescr() c_loop = cpu.compile_loop(None, [], ops, othertoken) - print "\n".join(map(str,c_loop[1])) deadframe = cpu.execute_token(othertoken) frame = rffi.cast(JITFRAMEPTR, deadframe) diff --git a/rpython/rtyper/test/test_rclass.py b/rpython/rtyper/test/test_rclass.py --- a/rpython/rtyper/test/test_rclass.py +++ b/rpython/rtyper/test/test_rclass.py @@ -1192,3 +1192,19 @@ assert self.interpret(f, [True]) == f(True) assert self.interpret(f, [False]) == f(False) + + def test_init_with_star_args(self): + class Base(object): + def __init__(self, a, b): + self.a = a + self.b = b + class A(Base): + def __init__(self, *args): + Base.__init__(self, *args) + self.c = -1 + cls = [Base, A] + + def f(k, a, b): + return cls[k](a, b).b + + assert self.interpret(f, [1, 4, 7]) == 7 diff --git a/rpython/translator/c/src/debug_print.c b/rpython/translator/c/src/debug_print.c --- a/rpython/translator/c/src/debug_print.c +++ b/rpython/translator/c/src/debug_print.c @@ -19,8 +19,8 @@ FILE *pypy_debug_file = NULL; /* XXX make it thread-local too? */ static unsigned char debug_ready = 0; static unsigned char debug_profile = 0; -__thread_if_stm static char debug_start_colors_1[32]; -__thread_if_stm static char debug_start_colors_2[28]; +static __thread_if_stm char debug_start_colors_1[32]; +static __thread_if_stm char debug_start_colors_2[28]; __thread_if_stm char pypy_debug_threadid[16] = {0}; static char *debug_stop_colors = ""; static char *debug_prefix = NULL; From noreply at buildbot.pypy.org Sat Sep 7 18:49:45 2013 From: noreply at buildbot.pypy.org (arigo) Date: Sat, 7 Sep 2013 18:49:45 +0200 (CEST) Subject: [pypy-commit] stmgc default: Ignore callbacks if we're outside a transaction or in an inevitable Message-ID: <20130907164945.549D01C0258@cobra.cs.uni-duesseldorf.de> Author: Armin Rigo Branch: Changeset: r524:782ebd6afc03 Date: 2013-09-07 18:48 +0200 http://bitbucket.org/pypy/stmgc/changeset/782ebd6afc03/ Log: Ignore callbacks if we're outside a transaction or in an inevitable transaction (which cannot abort) diff --git a/c4/extra.c b/c4/extra.c --- a/c4/extra.c +++ b/c4/extra.c @@ -25,6 +25,9 @@ void stm_call_on_abort(void *key, void callback(void *)) { struct tx_descriptor *d = thread_descriptor; + if (d == NULL || d->active != 1) + return; /* ignore callbacks if we're outside a transaction or + in an inevitable transaction (which cannot abort) */ if (callback == NULL) { /* ignore the return value: unregistered keys can be "deleted" again */ From noreply at buildbot.pypy.org Sat Sep 7 19:14:39 2013 From: noreply at buildbot.pypy.org (alex_gaynor) Date: Sat, 7 Sep 2013 19:14:39 +0200 (CEST) Subject: [pypy-commit] pypy default: This function is elidable Message-ID: <20130907171439.27C181C0112@cobra.cs.uni-duesseldorf.de> Author: Alex Gaynor Branch: Changeset: r66837:14ae990a97a7 Date: 2013-09-07 10:13 -0700 http://bitbucket.org/pypy/pypy/changeset/14ae990a97a7/ Log: This function is elidable diff --git a/rpython/rlib/rstring.py b/rpython/rlib/rstring.py --- a/rpython/rlib/rstring.py +++ b/rpython/rlib/rstring.py @@ -149,6 +149,7 @@ @specialize.argtype(0) + at jit.elidable def replace(input, sub, by, maxsplit=-1): if isinstance(input, str): assert isinstance(sub, str) From noreply at buildbot.pypy.org Sat Sep 7 19:14:40 2013 From: noreply at buildbot.pypy.org (alex_gaynor) Date: Sat, 7 Sep 2013 19:14:40 +0200 (CEST) Subject: [pypy-commit] pypy default: merged upstream Message-ID: <20130907171440.843CD1C0112@cobra.cs.uni-duesseldorf.de> Author: Alex Gaynor Branch: Changeset: r66838:e6e03b175e5f Date: 2013-09-07 10:14 -0700 http://bitbucket.org/pypy/pypy/changeset/e6e03b175e5f/ Log: merged upstream diff --git a/lib_pypy/_tkinter/tklib.py b/lib_pypy/_tkinter/tklib.py --- a/lib_pypy/_tkinter/tklib.py +++ b/lib_pypy/_tkinter/tklib.py @@ -1,6 +1,7 @@ # C bindings with libtcl and libtk. from cffi import FFI +import sys tkffi = FFI() @@ -102,6 +103,17 @@ int Tk_GetNumMainWindows(); """) +# XXX find a better way to detect paths +# XXX pick up CPPFLAGS and LDFLAGS and add to these paths? +if sys.platform.startswith("openbsd"): + incdirs = ['/usr/local/include/tcl8.5', '/usr/local/include/tk8.5', '/usr/X11R6/include'] + linklibs = ['tk85', 'tcl85'] + libdirs = ['/usr/local/lib', '/usr/X11R6/lib'] +else: + incdirs=['/usr/include/tcl'] + linklibs=['tcl', 'tk'] + libdirs = [] + tklib = tkffi.verify(""" #include #include @@ -109,6 +121,7 @@ char *get_tk_version() { return TK_VERSION; } char *get_tcl_version() { return TCL_VERSION; } """, -include_dirs=['/usr/include/tcl'], -libraries=['tcl', 'tk'], +include_dirs=incdirs, +libraries=linklibs, +library_dirs = libdirs ) diff --git a/pypy/interpreter/baseobjspace.py b/pypy/interpreter/baseobjspace.py --- a/pypy/interpreter/baseobjspace.py +++ b/pypy/interpreter/baseobjspace.py @@ -77,12 +77,12 @@ raise NotImplementedError("only for interp-level user subclasses " "from typedef.py") - def getname(self, space, default='?'): + def getname(self, space): try: return space.str_w(space.getattr(self, space.wrap('__name__'))) except OperationError, e: if e.match(space, space.w_TypeError) or e.match(space, space.w_AttributeError): - return default + return '?' raise def getaddrstring(self, space): diff --git a/pypy/interpreter/function.py b/pypy/interpreter/function.py --- a/pypy/interpreter/function.py +++ b/pypy/interpreter/function.py @@ -482,17 +482,16 @@ space.abstract_isinstance_w(w_firstarg, self.w_class)): pass # ok else: - clsdescr = self.w_class.getname(space, "") - if clsdescr: + clsdescr = self.w_class.getname(space) + if clsdescr and clsdescr != '?': clsdescr += " instance" else: clsdescr = "instance" if w_firstarg is None: instdescr = "nothing" else: - instname = space.abstract_getclass(w_firstarg).getname(space, - "") - if instname: + instname = space.abstract_getclass(w_firstarg).getname(space) + if instname and instname != '?': instdescr = instname + " instance" else: instdescr = "instance" diff --git a/pypy/interpreter/test/test_argument.py b/pypy/interpreter/test/test_argument.py --- a/pypy/interpreter/test/test_argument.py +++ b/pypy/interpreter/test/test_argument.py @@ -128,7 +128,7 @@ def type(self, obj): class Type: - def getname(self, space, default='?'): + def getname(self, space): return type(obj).__name__ return Type() 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 @@ -26,6 +26,9 @@ def try_ldflags(): yield ExternalCompilationInfo(libraries=['curses']) yield ExternalCompilationInfo(libraries=['curses', 'tinfo']) + yield ExternalCompilationInfo(libraries=['ncurses']) + yield ExternalCompilationInfo(libraries=['ncurses'], + library_dirs=['/usr/lib64']) def try_tools(): try: 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 @@ -175,8 +175,8 @@ state = '; dead' else: typename = space.type(w_obj).getname(space) - objname = w_obj.getname(space, '') - if objname: + objname = w_obj.getname(space) + if objname and objname != '?': state = "; to '%s' (%s)" % (typename, objname) else: state = "; to '%s'" % (typename,) diff --git a/pypy/objspace/descroperation.py b/pypy/objspace/descroperation.py --- a/pypy/objspace/descroperation.py +++ b/pypy/objspace/descroperation.py @@ -597,8 +597,8 @@ if num1 != num2: lt = num1 # if obj1 is a number, it is Lower Than obj2 else: - name1 = w_typ1.getname(space, "") - name2 = w_typ2.getname(space, "") + name1 = w_typ1.getname(space) + name2 = w_typ2.getname(space) if name1 != name2: lt = name1 < name2 else: 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 @@ -494,6 +494,12 @@ else: return w_self.name + def getname(w_self, space): + name = w_self.name + if name is None: + name = '?' + return name + def add_subclass(w_self, w_subclass): space = w_self.space if not space.config.translation.rweakref: 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 @@ -29,6 +29,7 @@ from rpython.rtyper.annlowlevel import llhelper, cast_instance_to_gcref from rpython.rtyper.lltypesystem import lltype, rffi from rpython.jit.backend.arm import callbuilder +from rpython.rtyper.lltypesystem.lloperation import llop class AssemblerARM(ResOpAssembler): @@ -1488,7 +1489,9 @@ def not_implemented(msg): - os.write(2, '[ARM/asm] %s\n' % msg) + msg = '[ARM/asm] %s\n' % msg + if we_are_translated(): + llop.debug_print(lltype.Void, msg) raise NotImplementedError(msg) 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 @@ -2,6 +2,8 @@ from rpython.jit.metainterp.history import Const, Box, REF, JitCellToken from rpython.rlib.objectmodel import we_are_translated, specialize from rpython.jit.metainterp.resoperation import rop +from rpython.rtyper.lltypesystem import lltype +from rpython.rtyper.lltypesystem.lloperation import llop try: from collections import OrderedDict @@ -753,5 +755,7 @@ def not_implemented(msg): - os.write(2, '[llsupport/regalloc] %s\n' % msg) + msg = '[llsupport/regalloc] %s\n' % msg + if we_are_translated(): + llop.debug_print(lltype.Void, msg) raise NotImplementedError(msg) 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 @@ -434,6 +434,7 @@ else: self.wb_slowpath[withcards + 2 * withfloats] = rawstart + @rgc.no_release_gil def assemble_loop(self, logger, loopname, inputargs, operations, looptoken, log): '''adds the following attributes to looptoken: @@ -513,6 +514,7 @@ return AsmInfo(ops_offset, rawstart + looppos, size_excluding_failure_stuff - looppos) + @rgc.no_release_gil def assemble_bridge(self, logger, faildescr, inputargs, operations, original_loop_token, log): if not we_are_translated(): @@ -2388,7 +2390,9 @@ return AddressLoc(ImmedLoc(addr), imm0, 0, 0) def not_implemented(msg): - os.write(2, '[x86/asm] %s\n' % msg) + msg = '[x86/asm] %s\n' % msg + if we_are_translated(): + llop.debug_print(lltype.Void, msg) raise NotImplementedError(msg) cond_call_register_arguments = [edi, esi, edx, ecx] 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 @@ -28,6 +28,7 @@ from rpython.rlib.rarithmetic import r_longlong, r_uint from rpython.rtyper.annlowlevel import cast_instance_to_gcref from rpython.rtyper.lltypesystem import lltype, rffi, rstr +from rpython.rtyper.lltypesystem.lloperation import llop class X86RegisterManager(RegisterManager): @@ -1375,7 +1376,9 @@ return base_ofs + WORD * (position + JITFRAME_FIXED_SIZE) def not_implemented(msg): - os.write(2, '[x86/regalloc] %s\n' % msg) + msg = '[x86/regalloc] %s\n' % msg + if we_are_translated(): + llop.debug_print(lltype.Void, msg) raise NotImplementedError(msg) # xxx hack: set a default value for TargetToken._ll_loop_code. 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 @@ -1,6 +1,7 @@ import py from rpython.rtyper.lltypesystem import lltype, llmemory, rffi from rpython.rlib.jit_hooks import LOOP_RUN_CONTAINER +from rpython.rlib import rgc from rpython.jit.backend.x86.assembler import Assembler386 from rpython.jit.backend.x86.regalloc import gpr_reg_mgr_cls, xmm_reg_mgr_cls from rpython.jit.backend.x86.profagent import ProfileAgent @@ -63,10 +64,12 @@ assert self.assembler is not None return RegAlloc(self.assembler, False) + @rgc.no_release_gil def setup_once(self): self.profile_agent.startup() self.assembler.setup_once() + @rgc.no_release_gil def finish_once(self): self.assembler.finish_once() self.profile_agent.shutdown() diff --git a/rpython/rlib/rgc.py b/rpython/rlib/rgc.py --- a/rpython/rlib/rgc.py +++ b/rpython/rlib/rgc.py @@ -262,7 +262,11 @@ keepalive_until_here(newp) return newp - +def no_release_gil(func): + func._dont_inline_ = True + func._no_release_gil_ = True + return func + def no_collect(func): func._dont_inline_ = True func._gc_no_collect_ = True diff --git a/rpython/rtyper/test/test_rclass.py b/rpython/rtyper/test/test_rclass.py --- a/rpython/rtyper/test/test_rclass.py +++ b/rpython/rtyper/test/test_rclass.py @@ -1192,3 +1192,19 @@ assert self.interpret(f, [True]) == f(True) assert self.interpret(f, [False]) == f(False) + + def test_init_with_star_args(self): + class Base(object): + def __init__(self, a, b): + self.a = a + self.b = b + class A(Base): + def __init__(self, *args): + Base.__init__(self, *args) + self.c = -1 + cls = [Base, A] + + def f(k, a, b): + return cls[k](a, b).b + + assert self.interpret(f, [1, 4, 7]) == 7 diff --git a/rpython/translator/backendopt/all.py b/rpython/translator/backendopt/all.py --- a/rpython/translator/backendopt/all.py +++ b/rpython/translator/backendopt/all.py @@ -10,6 +10,7 @@ from rpython.translator.backendopt.removeassert import remove_asserts from rpython.translator.backendopt.support import log from rpython.translator.backendopt.storesink import storesink_graph +from rpython.translator.backendopt import gilanalysis from rpython.flowspace.model import checkgraph INLINE_THRESHOLD_FOR_TEST = 33 @@ -138,6 +139,9 @@ for graph in graphs: checkgraph(graph) + gilanalysis.analyze(graphs, translator) + + def constfold(config, graphs): if config.constfold: for graph in graphs: diff --git a/rpython/translator/backendopt/gilanalysis.py b/rpython/translator/backendopt/gilanalysis.py new file mode 100644 --- /dev/null +++ b/rpython/translator/backendopt/gilanalysis.py @@ -0,0 +1,60 @@ +from rpython.translator.backendopt import graphanalyze + +# This is not an optimization. It checks for possible releases of the +# GIL in all graphs starting from rgc.no_release_gil. + + +class GilAnalyzer(graphanalyze.BoolGraphAnalyzer): + + def analyze_direct_call(self, graph, seen=None): + try: + func = graph.func + except AttributeError: + pass + else: + if getattr(func, '_gctransformer_hint_close_stack_', False): + return True + if getattr(func, '_transaction_break_', False): + return True + + return graphanalyze.BoolGraphAnalyzer.analyze_direct_call( + self, graph, seen) + + def analyze_external_call(self, op, seen=None): + funcobj = op.args[0].value._obj + if getattr(funcobj, 'transactionsafe', False): + return False + else: + return False + + def analyze_instantiate_call(self, seen=None): + return False + + def analyze_simple_operation(self, op, graphinfo): + return False + +def analyze(graphs, translator): + gilanalyzer = GilAnalyzer(translator) + for graph in graphs: + func = getattr(graph, 'func', None) + if func and getattr(func, '_no_release_gil_', False): + if gilanalyzer.analyze_direct_call(graph): + # 'no_release_gil' function can release the gil + import cStringIO + err = cStringIO.StringIO() + import sys + prev = sys.stdout + try: + sys.stdout = err + ca = GilAnalyzer(translator) + ca.verbose = True + ca.analyze_direct_call(graph) # print the "traceback" here + sys.stdout = prev + except: + sys.stdout = prev + # ^^^ for the dump of which operation in which graph actually + # causes it to return True + raise Exception("'no_release_gil' function can release the GIL:" + " %s\n%s" % (func, err.getvalue())) + + diff --git a/rpython/translator/backendopt/graphanalyze.py b/rpython/translator/backendopt/graphanalyze.py --- a/rpython/translator/backendopt/graphanalyze.py +++ b/rpython/translator/backendopt/graphanalyze.py @@ -1,6 +1,7 @@ from rpython.rtyper.lltypesystem.lltype import DelayedPointer from rpython.translator.simplify import get_graph from rpython.tool.algo.unionfind import UnionFind +from rpython.rtyper.lltypesystem import rclass class GraphAnalyzer(object): @@ -67,6 +68,9 @@ result, self.analyze_direct_call(graph, seen)) return result + def analyze_instantiate_call(self, seen=None): + return self.top_result() + def analyze_link(self, graph, link): return self.bottom_result() @@ -75,7 +79,7 @@ def compute_graph_info(self, graph): return None - def analyze(self, op, seen=None, graphinfo=None): + def analyze(self, op, seen=None, graphinfo=None, block=None): if op.opname == "direct_call": graph = get_graph(op.args[0], self.translator) if graph is None: @@ -90,6 +94,18 @@ elif op.opname == "indirect_call": graphs = op.args[-1].value if graphs is None: + if block is not None: + v_func = op.args[0] + for op1 in block.operations: + if (v_func is op1.result and + op1.opname == 'getfield' and + op1.args[0].concretetype == rclass.CLASSTYPE and + op1.args[1].value == 'instantiate'): + x = self.analyze_instantiate_call(seen) + if self.verbose and x: + self.dump_info('analyze_instantiate(%s): %r' % ( + graphs, x)) + return x if self.verbose: self.dump_info('%s to unknown' % (op,)) return self.top_result() @@ -127,7 +143,7 @@ for op in block.operations: result = self.add_to_result( result, - self.analyze(op, seen, graphinfo) + self.analyze(op, seen, graphinfo, block=block) ) if self.is_top_result(result): break @@ -161,7 +177,7 @@ graphs = self.translator.graphs for graph in graphs: for block, op in graph.iterblockops(): - self.analyze(op) + self.analyze(op, block=block) class Dependency(object): diff --git a/rpython/translator/backendopt/test/test_gilanalysis.py b/rpython/translator/backendopt/test/test_gilanalysis.py new file mode 100644 --- /dev/null +++ b/rpython/translator/backendopt/test/test_gilanalysis.py @@ -0,0 +1,80 @@ +import py + +from rpython.annotator.listdef import s_list_of_strings +from rpython.rtyper.lltypesystem import lltype, rffi +from rpython.translator.backendopt import gilanalysis +from rpython.memory.gctransform.test.test_transform import rtype +from rpython.translator.translator import graphof + +def test_canrelease_external(): + for ths in ['auto', True, False]: + for sbxs in [True, False]: + fext = rffi.llexternal('fext2', [], lltype.Void, + threadsafe=ths, sandboxsafe=sbxs) + def g(): + fext() + t = rtype(g, []) + gg = graphof(t, g) + + releases = (ths == 'auto' and not sbxs) or ths is True + assert releases == gilanalysis.GilAnalyzer(t).analyze_direct_call(gg) + +def test_canrelease_instantiate(): + class O: + pass + class A(O): + pass + class B(O): + pass + + classes = [A, B] + def g(i): + classes[i]() + + t = rtype(g, [int]) + gg = graphof(t, g) + assert not gilanalysis.GilAnalyzer(t).analyze_direct_call(gg) + + + +def test_no_release_gil(): + from rpython.rlib import rgc + + @rgc.no_release_gil + def g(): + return 1 + + assert g._dont_inline_ + assert g._no_release_gil_ + + def entrypoint(argv): + return g() + 2 + + t = rtype(entrypoint, [s_list_of_strings]) + gilanalysis.analyze(t.graphs, t) + + + +def test_no_release_gil_detect(gc="minimark"): + from rpython.rlib import rgc + + fext1 = rffi.llexternal('fext1', [], lltype.Void, threadsafe=True) + @rgc.no_release_gil + def g(): + fext1() + return 1 + + assert g._dont_inline_ + assert g._no_release_gil_ + + def entrypoint(argv): + return g() + 2 + + t = rtype(entrypoint, [s_list_of_strings]) + f = py.test.raises(Exception, gilanalysis.analyze, t.graphs, t) + expected = "'no_release_gil' function can release the GIL: Author: Armin Rigo Branch: Changeset: r66839:e64ff7db5200 Date: 2013-09-07 18:39 +0200 http://bitbucket.org/pypy/pypy/changeset/e64ff7db5200/ Log: kill dead code 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 @@ -8,20 +8,6 @@ #define OP_STACK_CURRENT(r) r = (Signed)&r -#define RAW_MALLOC_ZERO_FILLED 0 - -#if RAW_MALLOC_ZERO_FILLED - -#define OP_RAW_MALLOC(size, r, restype) { \ - r = (restype) PyObject_Malloc(size); \ - if (r != NULL) { \ - memset((void*)r, 0, size); \ - COUNT_MALLOC; \ - } \ - } - -#else - #define OP_RAW_MALLOC(size, r, restype) { \ r = (restype) PyObject_Malloc(size); \ if (r != NULL) { \ @@ -29,8 +15,6 @@ } \ } -#endif - #define OP_RAW_FREE(p, r) PyObject_Free(p); COUNT_FREE; #define OP_RAW_MEMCLEAR(p, size, r) memset((void*)p, 0, size) From noreply at buildbot.pypy.org Sat Sep 7 19:18:37 2013 From: noreply at buildbot.pypy.org (arigo) Date: Sat, 7 Sep 2013 19:18:37 +0200 (CEST) Subject: [pypy-commit] pypy stmgc-c4: import stmgc/782ebd6afc03 Message-ID: <20130907171837.8E01B1C0112@cobra.cs.uni-duesseldorf.de> Author: Armin Rigo Branch: stmgc-c4 Changeset: r66840:4cb6216967ca Date: 2013-09-07 18:49 +0200 http://bitbucket.org/pypy/pypy/changeset/4cb6216967ca/ Log: import stmgc/782ebd6afc03 diff --git a/rpython/translator/stm/src_stm/extra.c b/rpython/translator/stm/src_stm/extra.c --- a/rpython/translator/stm/src_stm/extra.c +++ b/rpython/translator/stm/src_stm/extra.c @@ -26,6 +26,9 @@ void stm_call_on_abort(void *key, void callback(void *)) { struct tx_descriptor *d = thread_descriptor; + if (d == NULL || d->active != 1) + return; /* ignore callbacks if we're outside a transaction or + in an inevitable transaction (which cannot abort) */ if (callback == NULL) { /* ignore the return value: unregistered keys can be "deleted" again */ diff --git a/rpython/translator/stm/src_stm/revision b/rpython/translator/stm/src_stm/revision --- a/rpython/translator/stm/src_stm/revision +++ b/rpython/translator/stm/src_stm/revision @@ -1,1 +1,1 @@ -4c80cba2b8ce +782ebd6afc03 From noreply at buildbot.pypy.org Sat Sep 7 19:18:38 2013 From: noreply at buildbot.pypy.org (arigo) Date: Sat, 7 Sep 2013 19:18:38 +0200 (CEST) Subject: [pypy-commit] pypy default: merge heads Message-ID: <20130907171838.AF76D1C0112@cobra.cs.uni-duesseldorf.de> Author: Armin Rigo Branch: Changeset: r66841:b9216461865e Date: 2013-09-07 19:17 +0200 http://bitbucket.org/pypy/pypy/changeset/b9216461865e/ Log: merge heads diff --git a/lib_pypy/_tkinter/tklib.py b/lib_pypy/_tkinter/tklib.py --- a/lib_pypy/_tkinter/tklib.py +++ b/lib_pypy/_tkinter/tklib.py @@ -110,8 +110,8 @@ linklibs = ['tk85', 'tcl85'] libdirs = ['/usr/local/lib', '/usr/X11R6/lib'] else: - incdirs=['/usr/include/tcl'], - linklibs=['tcl', 'tk'], + incdirs=['/usr/include/tcl'] + linklibs=['tcl', 'tk'] libdirs = [] tklib = tkffi.verify(""" diff --git a/rpython/rlib/rstring.py b/rpython/rlib/rstring.py --- a/rpython/rlib/rstring.py +++ b/rpython/rlib/rstring.py @@ -149,6 +149,7 @@ @specialize.argtype(0) + at jit.elidable def replace(input, sub, by, maxsplit=-1): if isinstance(input, str): assert isinstance(sub, str) From noreply at buildbot.pypy.org Sat Sep 7 19:27:10 2013 From: noreply at buildbot.pypy.org (arigo) Date: Sat, 7 Sep 2013 19:27:10 +0200 (CEST) Subject: [pypy-commit] pypy stmgc-c4: rstm.charp_inspect_abort_info() now turns the transaction inevitable. Must move the call Message-ID: <20130907172710.02DA81C014D@cobra.cs.uni-duesseldorf.de> Author: Armin Rigo Branch: stmgc-c4 Changeset: r66842:f65b3995ba1a Date: 2013-09-07 19:23 +0200 http://bitbucket.org/pypy/pypy/changeset/f65b3995ba1a/ Log: rstm.charp_inspect_abort_info() now turns the transaction inevitable. Must move the call to it after abort_and_retry() in the test. diff --git a/rpython/translator/stm/test/test_ztranslated.py b/rpython/translator/stm/test/test_ztranslated.py --- a/rpython/translator/stm/test/test_ztranslated.py +++ b/rpython/translator/stm/test/test_ztranslated.py @@ -250,12 +250,12 @@ globf.xy = 100 + retry_counter def check(_, retry_counter): - last = rstm.charp_inspect_abort_info() rstm.abort_info_push(globf, ('[', 'xy', ']', 'yx')) setxy(globf, retry_counter) if retry_counter < 3: rstm.abort_and_retry() # + last = rstm.charp_inspect_abort_info() print rffi.charp2str(last) print int(bool(rstm.charp_inspect_abort_info())) # From noreply at buildbot.pypy.org Sat Sep 7 19:27:11 2013 From: noreply at buildbot.pypy.org (arigo) Date: Sat, 7 Sep 2013 19:27:11 +0200 (CEST) Subject: [pypy-commit] pypy stmgc-c4: Fix raw mallocs to be freed in case of an abort occurring at the wrong Message-ID: <20130907172711.309C21C087E@cobra.cs.uni-duesseldorf.de> Author: Armin Rigo Branch: stmgc-c4 Changeset: r66843:ad626a2c303c Date: 2013-09-07 19:26 +0200 http://bitbucket.org/pypy/pypy/changeset/ad626a2c303c/ Log: Fix raw mallocs to be freed in case of an abort occurring at the wrong time. diff --git a/rpython/translator/c/src/mem.c b/rpython/translator/c/src/mem.c --- a/rpython/translator/c/src/mem.c +++ b/rpython/translator/c/src/mem.c @@ -3,6 +3,35 @@ #include #include + +#ifdef RPY_STM +# include "src/mem.h" +# include "src/allocator.h" +# ifdef RPY_ASSERT +int try_pypy_debug_alloc_stop(void *); +# else +# define try_pypy_debug_alloc_stop(p) /* nothing */ +# endif +void _pypy_stm_free(void *ptr) +{ + /* This is called by src_stm/*.c when the transaction is aborted + and the 'ptr' was malloced but not freed. We have first to + unregister the object with a tentative pypy_debug_alloc_stop(), + which ignores it if it was not actually registered. Then we + free the object in the normal way. Finally we increment the + free counter to keep it in sync. */ + try_pypy_debug_alloc_stop(ptr); + PyObject_Free(ptr); + COUNT_FREE; +} +#endif + + +#ifdef COUNT_OP_MALLOCS +int count_mallocs=0, count_frees=0; +#endif + + /*** tracking raw mallocs and frees for debugging ***/ #ifdef RPY_ASSERT @@ -35,7 +64,7 @@ spinlock_release(pypy_debug_alloc_lock); } -void pypy_debug_alloc_stop(void *addr) +int try_pypy_debug_alloc_stop(void *addr) { struct pypy_debug_alloc_s **p; spinlock_acquire(pypy_debug_alloc_lock, '-'); @@ -47,9 +76,15 @@ *p = dying->next; spinlock_release(pypy_debug_alloc_lock); free(dying); - return; + return 1; } - RPyAssert(0, "free() of a never-malloc()ed object"); + return 0; +} + +void pypy_debug_alloc_stop(void *addr) +{ + if (!try_pypy_debug_alloc_stop(addr)) + RPyAssert(0, "free() of a never-malloc()ed object"); } void pypy_debug_alloc_results(void) 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 @@ -11,30 +11,26 @@ #define OP_STACK_CURRENT(r) r = (Signed)&r -#define RAW_MALLOC_ZERO_FILLED 0 +#ifdef RPY_STM +void _pypy_stm_free(void *); +#define _OP_RAW_MALLOCED(r) stm_call_on_abort(r, _pypy_stm_free) +#define _OP_RAW_STM_UNREGISTER(r) stm_call_on_abort(r, NULL) +#else +#define _OP_RAW_MALLOCED(r) /* nothing */ +#define _OP_RAW_STM_UNREGISTER(r) /* nothing */ +#endif -#if RAW_MALLOC_ZERO_FILLED - -#define OP_RAW_MALLOC(size, r, restype) { \ - r = (restype) PyObject_Malloc(size); \ - if (r != NULL) { \ - memset((void*)r, 0, size); \ - COUNT_MALLOC; \ - } \ - } - -#else #define OP_RAW_MALLOC(size, r, restype) { \ r = (restype) PyObject_Malloc(size); \ if (r != NULL) { \ COUNT_MALLOC; \ + _OP_RAW_MALLOCED(r); \ } \ } -#endif - -#define OP_RAW_FREE(p, r) PyObject_Free(p); COUNT_FREE; +#define OP_RAW_FREE(p, r) PyObject_Free(p); COUNT_FREE; \ + _OP_RAW_STM_UNREGISTER(p); #define OP_RAW_MEMCLEAR(p, size, r) memset((void*)p, 0, size) @@ -63,7 +59,7 @@ #else /* COUNT_OP_MALLOCS */ -static int count_mallocs=0, count_frees=0; +extern int count_mallocs, count_frees; #define COUNT_MALLOC count_mallocs++ #define COUNT_FREE count_frees++ diff --git a/rpython/translator/stm/test/test_inevitable.py b/rpython/translator/stm/test/test_inevitable.py --- a/rpython/translator/stm/test/test_inevitable.py +++ b/rpython/translator/stm/test/test_inevitable.py @@ -114,8 +114,6 @@ res = self.interpret_inevitable(f1, []) assert res is None - assert 0, """we do not turn inevitable before - raw-mallocs which causes leaks on aborts""" def test_raw_malloc_2(self): X = lltype.Struct('X', ('foo', lltype.Signed)) @@ -126,8 +124,6 @@ res = self.interpret_inevitable(f1, []) assert res is None - assert 0, """we do not turn inevitable before - raw-mallocs which causes leaks on aborts""" def test_unknown_raw_free(self): X = lltype.Struct('X', ('foo', lltype.Signed)) diff --git a/rpython/translator/stm/test/test_ztranslated.py b/rpython/translator/stm/test/test_ztranslated.py --- a/rpython/translator/stm/test/test_ztranslated.py +++ b/rpython/translator/stm/test/test_ztranslated.py @@ -1,5 +1,7 @@ from rpython.rlib import rstm, rgc, objectmodel +from rpython.rlib.debug import debug_print from rpython.rtyper.lltypesystem import lltype, rffi +from rpython.rtyper.lltypesystem.rclass import OBJECTPTR from rpython.rtyper.lltypesystem.lloperation import llop from rpython.translator.stm.test.support import CompiledSTMTests from rpython.translator.stm.test import targetdemo2 @@ -131,7 +133,6 @@ rgc.collect(0) return 0 # - from rpython.rtyper.lltypesystem.rclass import OBJECTPTR S = lltype.GcStruct('S', ('got_exception', OBJECTPTR)) PS = lltype.Ptr(S) perform_transaction = rstm.make_perform_transaction(check, PS) @@ -162,7 +163,6 @@ pass prebuilt2 = [X2(), X2()] # - from rpython.rtyper.lltypesystem.rclass import OBJECTPTR S = lltype.GcStruct('S', ('got_exception', OBJECTPTR)) PS = lltype.Ptr(S) perform_transaction = rstm.make_perform_transaction(check, PS) @@ -190,7 +190,6 @@ def test_prebuilt_nongc(self): def check(foobar, retry_counter): return 0 # do nothing - from rpython.rtyper.lltypesystem.rclass import OBJECTPTR from rpython.rtyper.lltypesystem import lltype S = lltype.GcStruct('S', ('got_exception', OBJECTPTR)) PS = lltype.Ptr(S) @@ -237,8 +236,6 @@ assert 'ok\n' in data def test_abort_info(self): - from rpython.rtyper.lltypesystem.rclass import OBJECTPTR - class Parent(object): pass class Foobar(Parent): @@ -329,3 +326,35 @@ t, cbuilder = self.compile(main) data = cbuilder.cmdexec('') assert 'test ok\n' in data + + def test_raw_malloc_no_leak(self): + FOOARRAY = lltype.Array(lltype.Signed) + + def check(_, retry_counter): + x = lltype.malloc(FOOARRAY, 100000, flavor='raw') + if retry_counter < 1000: + if (retry_counter & 3) == 0: + lltype.free(x, flavor='raw') + debug_print(rffi.cast(lltype.Signed, x)) + rstm.abort_and_retry() + lltype.free(x, flavor='raw') + return 0 + + PS = lltype.Ptr(lltype.GcStruct('S', ('got_exception', OBJECTPTR))) + perform_transaction = rstm.make_perform_transaction(check, PS) + + def main(argv): + perform_transaction(lltype.nullptr(PS.TO)) + return 0 + + t, cbuilder = self.compile(main) + data, dataerr = cbuilder.cmdexec('', err=True) + lines = dataerr.split('\n') + assert len(lines) > 1000 + addresses = map(int, lines[:1000]) + assert len(addresses) == 1000 + assert len(set(addresses)) < 500 # should ideally just be a few + import re + match = re.search(r"(\d+) mallocs left", dataerr) + assert match + assert int(match.group(1)) < 20 From noreply at buildbot.pypy.org Sat Sep 7 20:06:37 2013 From: noreply at buildbot.pypy.org (arigo) Date: Sat, 7 Sep 2013 20:06:37 +0200 (CEST) Subject: [pypy-commit] pypy stmgc-c4: Fix? Message-ID: <20130907180637.AFED11C014D@cobra.cs.uni-duesseldorf.de> Author: Armin Rigo Branch: stmgc-c4 Changeset: r66844:6db8370436ba Date: 2013-09-07 20:06 +0200 http://bitbucket.org/pypy/pypy/changeset/6db8370436ba/ Log: Fix? diff --git a/rpython/translator/stm/writebarrier.py b/rpython/translator/stm/writebarrier.py --- a/rpython/translator/stm/writebarrier.py +++ b/rpython/translator/stm/writebarrier.py @@ -134,7 +134,7 @@ def get_category_or_null(v): # 'v' is an original variable here, or a constant if isinstance(v, Constant) and not v.value: # a NULL constant - return None + return 'Z' if v in renamings: return renamings[v].category if isinstance(v, Constant): @@ -205,7 +205,7 @@ if op in self.expand_comparison: cats = (get_category_or_null(op.args[0]), get_category_or_null(op.args[1])) - if None not in cats and (cats[0] < 'V' or cats[1] < 'V'): + if 'Z' not in cats and (cats[0] < 'V' or cats[1] < 'V'): if newop.opname == 'ptr_ne': v = varoftype(lltype.Bool) negop = SpaceOperation('bool_not', [v], @@ -346,6 +346,7 @@ * 'R': the read barrier was applied * 'V': same as W, except needs a repeat_write_barrier * 'W': the write barrier was applied + * 'Z': the null constant The letters are chosen so that a barrier is needed to change a pointer from category x to category y if and only if y > x. From noreply at buildbot.pypy.org Sat Sep 7 20:11:18 2013 From: noreply at buildbot.pypy.org (arigo) Date: Sat, 7 Sep 2013 20:11:18 +0200 (CEST) Subject: [pypy-commit] pypy stmgc-c4: Yes, it was a fix. Here's the test. Message-ID: <20130907181118.390221C0112@cobra.cs.uni-duesseldorf.de> Author: Armin Rigo Branch: stmgc-c4 Changeset: r66845:bd5b23f0f700 Date: 2013-09-07 20:10 +0200 http://bitbucket.org/pypy/pypy/changeset/bd5b23f0f700/ Log: Yes, it was a fix. Here's the test. diff --git a/rpython/translator/stm/test/test_writebarrier.py b/rpython/translator/stm/test/test_writebarrier.py --- a/rpython/translator/stm/test/test_writebarrier.py +++ b/rpython/translator/stm/test/test_writebarrier.py @@ -28,6 +28,24 @@ assert len(self.writemode) == 0 assert self.barriers == ['I2R'] + def test_simple_read_2(self): + X = lltype.GcStruct('X', ('foo', lltype.Signed)) + x2 = lltype.malloc(X, immortal=True) + x2.foo = 81 + null = lltype.nullptr(X) + + def f1(n): + if n < 1: + p = null + else: + p = x2 + return p.foo + + res = self.interpret(f1, [4]) + assert res == 81 + assert len(self.writemode) == 0 + assert self.barriers == ['I2R'] + def test_simple_write(self): X = lltype.GcStruct('X', ('foo', lltype.Signed)) x1 = lltype.malloc(X, immortal=True) From noreply at buildbot.pypy.org Sat Sep 7 20:17:12 2013 From: noreply at buildbot.pypy.org (alex_gaynor) Date: Sat, 7 Sep 2013 20:17:12 +0200 (CEST) Subject: [pypy-commit] pypy unroll-virtual-dict-resize: Start hacking on this, doesn't work because heapcache doesn't handle GETINTERIORFIELD/SETINTERIOFIELD Message-ID: <20130907181712.71A721C0112@cobra.cs.uni-duesseldorf.de> Author: Alex Gaynor Branch: unroll-virtual-dict-resize Changeset: r66846:42b97400acf7 Date: 2013-09-07 11:16 -0700 http://bitbucket.org/pypy/pypy/changeset/42b97400acf7/ Log: Start hacking on this, doesn't work because heapcache doesn't handle GETINTERIORFIELD/SETINTERIOFIELD diff --git a/rpython/jit/codewriter/support.py b/rpython/jit/codewriter/support.py --- a/rpython/jit/codewriter/support.py +++ b/rpython/jit/codewriter/support.py @@ -522,8 +522,6 @@ return LLtypeHelpers._dictnext_items(lltype.Ptr(RES), iter) _ll_1_dictiter_nextitems.need_result_type = True - _ll_1_dict_resize = ll_rdict.ll_dict_resize - # ---------- strings and unicode ---------- _ll_1_str_str2unicode = ll_rstr.LLHelpers.ll_str2unicode 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 @@ -27,6 +27,9 @@ # heap array cache # maps descrs to {index: {from_box: to_box}} dicts self.heap_array_cache = {} + # heap array of struct cache + # maps descrs to {index: {descr: {from_box: to_box}}} + self.heap_array_struct_cache = {} # cache the length of arrays self.length_cache = {} diff --git a/rpython/jit/metainterp/test/test_dict.py b/rpython/jit/metainterp/test/test_dict.py --- a/rpython/jit/metainterp/test/test_dict.py +++ b/rpython/jit/metainterp/test/test_dict.py @@ -1,7 +1,6 @@ -import py from rpython.jit.metainterp.test.support import LLJitMixin +from rpython.rlib import objectmodel, jit from rpython.rlib.jit import JitDriver -from rpython.rlib import objectmodel class DictTests: @@ -177,6 +176,29 @@ self.check_simple_loop({'int_sub': 1, 'int_gt': 1, 'guard_true': 1, 'jump': 1}) + def test_look_inside_resize(self): + driver = JitDriver(greens=[], reds=['n', 'j']) + + def f(n, j): + while n > 0: + driver.jit_merge_point(n=n, j=j) + jit.promote(j) + d = { + j: j, + j + 1: j, + j + 2: j, + j + 3: j, + j + 4: j, + j + 5: j + } + n -= (len(d) - 5) + return n + + res = self.meta_interp(f, [10, 2], listops=True) + assert res == f(10, 2) + self.check_simple_loop({'int_sub': 1, 'int_gt': 1, 'guard_true': 1, + 'jump': 1}) + class TestLLtype(DictTests, LLJitMixin): pass diff --git a/rpython/rtyper/lltypesystem/rdict.py b/rpython/rtyper/lltypesystem/rdict.py --- a/rpython/rtyper/lltypesystem/rdict.py +++ b/rpython/rtyper/lltypesystem/rdict.py @@ -536,6 +536,7 @@ # call which is opaque to the JIT when the dict isn't virtual, to # avoid extra branches. + at jit.look_inside_iff(lambda d: jit.isvirtual(d)) def ll_dict_resize(d): old_entries = d.entries old_size = len(old_entries) @@ -560,7 +561,6 @@ ll_dict_insertclean(d, entry.key, entry.value, hash) i += 1 old_entries.delete() -ll_dict_resize.oopspec = 'dict.resize(d)' # ------- a port of CPython's dictobject.c's lookdict implementation ------- PERTURB_SHIFT = 5 @@ -627,6 +627,7 @@ freeslot = intmask(i) perturb >>= PERTURB_SHIFT + at jit.look_inside_iff(lambda d, hash: jit.isvirtual(d) and jit.isconstant(hash)) def ll_dict_lookup_clean(d, hash): # a simplified version of ll_dict_lookup() which assumes that the # key is new, and the dictionary doesn't contain deleted entries. From noreply at buildbot.pypy.org Sun Sep 8 16:06:22 2013 From: noreply at buildbot.pypy.org (bivab) Date: Sun, 8 Sep 2013 16:06:22 +0200 (CEST) Subject: [pypy-commit] buildbot default: add a buildstep to extract and update the changeset-id from the revision property of a SourceStamp Message-ID: <20130908140622.C2CE51C0315@cobra.cs.uni-duesseldorf.de> Author: David Schneider Branch: Changeset: r859:3eaa460b6947 Date: 2013-09-08 15:53 +0200 http://bitbucket.org/pypy/buildbot/changeset/3eaa460b6947/ Log: add a buildstep to extract and update the changeset-id from the revision property of a SourceStamp diff --git a/bot2/pypybuildbot/builds.py b/bot2/pypybuildbot/builds.py --- a/bot2/pypybuildbot/builds.py +++ b/bot2/pypybuildbot/builds.py @@ -1,10 +1,12 @@ from buildbot.steps.source.mercurial import Mercurial +from buildbot.process.buildstep import BuildStep from buildbot.process import factory from buildbot.steps import shell, transfer from buildbot.steps.trigger import Trigger from buildbot.process.properties import WithProperties from buildbot import locks from pypybuildbot.util import symlink_force +from buildbot.status.results import SKIPPED, SUCCESS import os # buildbot supports SlaveLocks, which can be used to limit the amout of builds @@ -168,6 +170,21 @@ builder.saveYourself() # _______________________________________________________________ +# XXX Currently the build properties got_revision and final_file_name contain +# the revision number and the changeset-id, CheckGotRevision takes care to set +# the corresponding build properties +# rev:changeset for got_revision +# rev-changeset for final_file_name +# +# The rev part of got_revision and filename is used everywhere to sort the +# builds, i.e. on the summary and download pages. +# +# The rev part is strictly local and needs to be removed from the SourceStamp, +# at least for decoupled builds, which is what ParseRevision does. +# +# XXX in general it would be nice to drop the revision-number using only the +# changeset-id for got_revision and final_file_name and sorting the builds +# chronologically class CheckGotRevision(ShellCmd): description = 'got_revision' command = ['hg', 'parents', '--template', 'got_revision:{rev}:{node}'] @@ -189,6 +206,34 @@ self.build.setProperty('final_file_name', final_file_name, 'got_revision') +class ParseRevision(BuildStep): + """Parse the revision property of the source stamp and extract the global + part of the revision + 123:3a34 -> 3a34""" + name = "parse_revision" + + def __init__(self, *args, **kwargs): + BuildStep.__init__(self, *args, **kwargs) + + @staticmethod + def hideStepIf(results, step): + return results==SKIPPED + + @staticmethod + def doStepIf(step): + revision = step.build.getSourceStamp().revision + return isinstance(revision, (unicode, str)) and ':' in revision + + def start(self): + stamp = self.build.getSourceStamp() + revision = stamp.revision + if isinstance(revision, (unicode, str)) and ':' in revision: + parts = revision.split(':') + self.build.setProperty('revision', parts[1], 'parse_revision') + stamp.revision = parts[1] + self.finished(SUCCESS) + + def update_hg(platform, factory, repourl, workdir, use_branch, force_branch=None): factory.addStep( @@ -212,6 +257,9 @@ # for debugging repourl = '/home/antocuni/pypy/default' # + factory.addStep(ParseRevision(hideStepIf=ParseRevision.hideStepIf, + doStepIf=ParseRevision.doStepIf)) + # update_hg(platform, factory, repourl, workdir, use_branch=True, force_branch=force_branch) # @@ -476,7 +524,7 @@ basename=name + extension, workdir='.', blocksize=100 * 1024)) - if trigger: # if provided trigger schedulers that are depend on this one + if trigger: # if provided trigger schedulers that depend on this one self.addStep(Trigger(schedulerNames=[trigger])) diff --git a/bot2/pypybuildbot/test/test_builds.py b/bot2/pypybuildbot/test/test_builds.py --- a/bot2/pypybuildbot/test/test_builds.py +++ b/bot2/pypybuildbot/test/test_builds.py @@ -4,37 +4,67 @@ class FakeProperties(object): - def __init__(self): - pass - + sources = {} + + def __init__(self, properties=None): + if properties is None: + self.properties = {'branch':None, 'got_revision': 123, + 'final_file_name': '123-ea5ca8'} + else: + self.properties = properties + def __getitem__(self, item): - if item == 'branch': - return None - if item == 'got_revision': - return 123 - if item == 'final_file_name': - return '123-ea5ca8' - + return self.properties.get(item) + + def __setitem__(self, name, value): + self.properties[name] = value + def render(self, x): return x +class FakeSourceStamp(object): + def __init__(self, properties=None): + self.properties = properties if properties is not None else {} + + def __getattr__(self, name): + return self.properties.get(name) + + def __setattribute__(self, name, value): + self.properties[name] = value + class FakeBuild(object): slaveEnvironment = None - def __init__(self): - self.properties = FakeProperties() - + def __init__(self, properties=None): + self.properties = FakeProperties(properties) + self.source_stamp = FakeSourceStamp(properties) + def getProperties(self): return self.properties + def setProperty(self, name, value, source): + self.properties[name] = value + self.properties.sources[name] = source + def getSlaveCommandVersion(self, *args): return 3 + def getSourceStamp(self, *args): + return self.source_stamp + class FakeStepStatus(object): def setText(self, *args): pass + def stepFinished(self, results): + self.results = results + + def setHidden(self, *args): + pass + class FakeDeferred(object): + def callback(*args): + pass def addCallback(self, *args): return FakeDeferred() def addErrback(self, *args): @@ -146,3 +176,34 @@ step.commandComplete(cmd) summary = builder.summary_by_branch_and_revision[('trunk', '123')] assert summary.to_tuple() == (2, 2, 4, 0) + + +class TestParseRevision(object): + + def setup_method(self, mth): + inst = builds.ParseRevision() + factory = inst._getStepFactory().factory + kw = inst._getStepFactory().kwargs + self.rebuilt = factory(**kw) + self.rebuilt.step_status = FakeStepStatus() + self.rebuilt.deferred = FakeDeferred() + + def test_has_revision(self): + self.rebuilt.build = FakeBuild({'revision':u'123:ea5ca8'}) + self.rebuilt.start() + assert self.rebuilt.build.getProperties()['revision'] == 'ea5ca8' + + def test_no_revision(self): + self.rebuilt.build = FakeBuild() + self.rebuilt.start() + assert self.rebuilt.build.getProperties()['revision'] is None + + def test_revision_no_local_part(self): + self.rebuilt.build = FakeBuild({'revision':u'ea5ca8'}) + self.rebuilt.start() + assert self.rebuilt.build.getProperties()['revision'] == 'ea5ca8' + + def test_empty_revision(self): + self.rebuilt.build = FakeBuild({'revision':u''}) + self.rebuilt.start() + assert self.rebuilt.build.getProperties()['revision'] == '' From noreply at buildbot.pypy.org Sun Sep 8 16:06:23 2013 From: noreply at buildbot.pypy.org (bivab) Date: Sun, 8 Sep 2013 16:06:23 +0200 (CEST) Subject: [pypy-commit] buildbot default: add a builder to run the buildbot tests Message-ID: <20130908140623.E54831C12DA@cobra.cs.uni-duesseldorf.de> Author: David Schneider Branch: Changeset: r860:bde33c8ace0d Date: 2013-09-08 16:01 +0200 http://bitbucket.org/pypy/buildbot/changeset/bde33c8ace0d/ Log: add a builder to run the buildbot tests diff --git a/.hgignore b/.hgignore --- a/.hgignore +++ b/.hgignore @@ -34,3 +34,5 @@ *-win-32 *-win-x86-32 *-win-x86-64 +slave/pypy-buildbot +master/pypy-buildbot diff --git a/bot2/pypybuildbot/master.py b/bot2/pypybuildbot/master.py --- a/bot2/pypybuildbot/master.py +++ b/bot2/pypybuildbot/master.py @@ -180,6 +180,8 @@ JITBENCH64_2 = 'jit-benchmark-linux-x86-64-2' CPYTHON_64 = "cpython-2-benchmark-x86-64" +# buildbot builder +PYPYBUILDBOT = 'pypy-buildbot' extra_opts = {'xerxes': {'keepalive_interval': 15}, 'aurora': {'max_builds': 1}, @@ -213,6 +215,8 @@ JITFREEBSD864, # on ananke JITFREEBSD964, # on exarkun's freebsd JITMACOSX64, # on xerxes + # buildbot selftest + PYPYBUILDBOT # on cobra ], branch='default', hour=0, minute=0), Nightly("nightly-2-00", [ @@ -228,8 +232,9 @@ Nightly("nighly-ppc", [ JITONLYLINUXPPC64, # on gcc1 ], branch='ppc-jit-backend', hour=1, minute=0), - CustomForceScheduler('Force Scheduler', + CustomForceScheduler('Force Scheduler', builderNames=[ + PYPYBUILDBOT, LINUX32, LINUX64, INDIANA32, @@ -420,6 +425,13 @@ 'factory': pypyOwnTestFactoryIndiana, 'category': 'openindiana32', }, + {'name': PYPYBUILDBOT, + 'slavenames': ['cobra'], + 'builddir': PYPYBUILDBOT, + 'factory': pypybuilds.PyPyBuildbotTestFactory(), + 'category': 'buildbot', + } + ] + ARM.builders, # http://readthedocs.org/docs/buildbot/en/latest/tour.html#debugging-with-manhole From noreply at buildbot.pypy.org Sun Sep 8 18:28:33 2013 From: noreply at buildbot.pypy.org (rlamy) Date: Sun, 8 Sep 2013 18:28:33 +0200 (CEST) Subject: [pypy-commit] pypy less-stringly-ops: Turn FSException into a normal object, not an exception. Message-ID: <20130908162833.0CE2B1C0315@cobra.cs.uni-duesseldorf.de> Author: Ronan Lamy Branch: less-stringly-ops Changeset: r66847:e78d34c539f7 Date: 2013-09-06 19:45 +0100 http://bitbucket.org/pypy/pypy/changeset/e78d34c539f7/ Log: Turn FSException into a normal object, not an exception. FSException now unambiguously represents RPython-level exception objects, and is separate from the internal translator-level exceptions used by flowspace to implement control flow. diff --git a/rpython/flowspace/flowcontext.py b/rpython/flowspace/flowcontext.py --- a/rpython/flowspace/flowcontext.py +++ b/rpython/flowspace/flowcontext.py @@ -34,10 +34,13 @@ def __init__(self, value): self.value = value -class RaiseImplicit(Exception): +class Raise(Exception): def __init__(self, value): self.value = value +class RaiseImplicit(Raise): + pass + class BytecodeCorruption(Exception): pass @@ -486,11 +489,12 @@ link = Link([w_type, w_value], self.graph.exceptblock) self.recorder.crnt_block.closeblock(link) - except FSException, e: - if e.w_type == self.space.w_ImportError: + except Raise as e: + w_exc = e.value + if w_exc.w_type == self.space.w_ImportError: msg = 'import statement always raises %s' % e raise ImportError(msg) - link = Link([e.w_type, e.w_value], self.graph.exceptblock) + link = Link([w_exc.w_type, w_exc.w_value], self.graph.exceptblock) self.recorder.crnt_block.closeblock(link) except StopFlowing: @@ -566,12 +570,8 @@ return res if res is not None else next_instr except RaiseImplicit as e: return SImplicitException(e.value).unroll(self) - except FSException, operr: - return self.handle_operation_error(operr) - - def handle_operation_error(self, operr): - unroller = SApplicationException(operr) - return unroller.unroll(self) + except Raise as e: + return SApplicationException(e.value).unroll(self) def getlocalvarname(self, index): return self.pycode.co_varnames[index] @@ -638,10 +638,11 @@ space = self.space if nbargs == 0: if self.last_exception is not None: - raise self.last_exception + w_exc = self.last_exception else: - raise const(TypeError( + w_exc = const(TypeError( "raise: no active exception to re-raise")) + raise Raise(w_exc) if nbargs >= 3: self.popvalue() @@ -655,7 +656,7 @@ operror = w_type else: operror = space.exc_from_raise(w_type, space.w_None) - raise operror + raise Raise(operror) def IMPORT_NAME(self, nameindex): space = self.space @@ -775,7 +776,7 @@ w_iterator = self.peekvalue() try: w_nextitem = self.space.next(w_iterator) - except RaiseImplicit as e: + except Raise as e: w_exc = e.value if not self.space.exception_match(w_exc.w_type, self.space.w_StopIteration): @@ -783,12 +784,6 @@ # iterator exhausted self.popvalue() return target - except FSException as e: - if not self.space.exception_match(e.w_type, self.space.w_StopIteration): - raise - # iterator exhausted - self.popvalue() - return target else: self.pushvalue(w_nextitem) @@ -1187,7 +1182,7 @@ self.operr = operr def nomoreblocks(self): - raise self.operr + raise Raise(self.operr) def state_unpack_variables(self): return [self.operr.w_type, self.operr.w_value] diff --git a/rpython/flowspace/model.py b/rpython/flowspace/model.py --- a/rpython/flowspace/model.py +++ b/rpython/flowspace/model.py @@ -346,7 +346,7 @@ return False -class FSException(Exception): +class FSException(object): def __init__(self, w_type, w_value): assert w_type is not None self.w_type = w_type diff --git a/rpython/flowspace/objspace.py b/rpython/flowspace/objspace.py --- a/rpython/flowspace/objspace.py +++ b/rpython/flowspace/objspace.py @@ -13,7 +13,7 @@ from rpython.flowspace.bytecode import HostCode from rpython.flowspace.operation import op, NOT_REALLY_CONST from rpython.flowspace.flowcontext import (FlowSpaceFrame, fixeggblocks, - FlowingError) + FlowingError, Raise) from rpython.flowspace.generator import (tweak_generator_graph, bootstrap_generator) from rpython.flowspace.pygraph import PyGraph @@ -150,8 +150,9 @@ else: # the only case left here is (inst, None), from a 'raise inst'. if not frame.guessbool(self.is_(w_arg2, self.w_None)): - raise const(TypeError( - "instance exception may not have a separate value")) + exc = TypeError("instance exception may not have a " + "separate value") + raise Raise(const(exc)) w_value = w_arg1 w_type = self.type(w_value) return FSException(w_type, w_value) @@ -173,8 +174,8 @@ w_len = self.len(w_iterable) w_correct = self.eq(w_len, const(expected_length)) if not self.frame.guessbool(self.bool(w_correct)): - e = self.exc_from_raise(self.w_ValueError, self.w_None) - raise e + w_exc = self.exc_from_raise(self.w_ValueError, self.w_None) + raise Raise(w_exc) return [self.frame.do_operation('getitem', w_iterable, const(i)) for i in range(expected_length)] @@ -187,7 +188,7 @@ try: mod = __import__(name, glob, loc, frm, level) except ImportError as e: - raise const(e) + raise Raise(const(e)) return const(mod) def import_from(self, w_module, w_name): @@ -201,7 +202,8 @@ try: return const(getattr(w_module.value, w_name.value)) except AttributeError: - raise const(ImportError("cannot import name '%s'" % w_name.value)) + exc = ImportError("cannot import name '%s'" % w_name.value) + raise Raise(const(exc)) def call_method(self, w_obj, methname, *arg_w): w_meth = self.getattr(w_obj, const(methname)) diff --git a/rpython/flowspace/operation.py b/rpython/flowspace/operation.py --- a/rpython/flowspace/operation.py +++ b/rpython/flowspace/operation.py @@ -330,7 +330,8 @@ try: v, next_unroller = it.step() except IndexError: - raise const(StopIteration()) + from rpython.flowspace.flowcontext import Raise + raise Raise(const(StopIteration())) else: frame.replace_in_stack(it, next_unroller) return const(v) From noreply at buildbot.pypy.org Sun Sep 8 18:28:34 2013 From: noreply at buildbot.pypy.org (rlamy) Date: Sun, 8 Sep 2013 18:28:34 +0200 (CEST) Subject: [pypy-commit] pypy less-stringly-ops: Move the unroll() method to FSFrame Message-ID: <20130908162834.26E8D1C0315@cobra.cs.uni-duesseldorf.de> Author: Ronan Lamy Branch: less-stringly-ops Changeset: r66848:f92925dcd696 Date: 2013-09-07 17:39 +0100 http://bitbucket.org/pypy/pypy/changeset/f92925dcd696/ Log: Move the unroll() method to FSFrame Rename SuspendedUnroller to something more descrptive of its intended role. diff --git a/rpython/flowspace/flowcontext.py b/rpython/flowspace/flowcontext.py --- a/rpython/flowspace/flowcontext.py +++ b/rpython/flowspace/flowcontext.py @@ -569,9 +569,17 @@ res = getattr(self, methodname)(oparg) return res if res is not None else next_instr except RaiseImplicit as e: - return SImplicitException(e.value).unroll(self) + return self.unroll(SImplicitException(e.value)) except Raise as e: - return SApplicationException(e.value).unroll(self) + return self.unroll(SApplicationException(e.value)) + + def unroll(self, signal): + while self.blockstack: + block = self.blockstack.pop() + if isinstance(signal, block.handles): + return block.handle(self, signal) + block.cleanupstack(self) + return signal.nomoreblocks() def getlocalvarname(self, index): return self.pycode.co_varnames[index] @@ -589,11 +597,10 @@ raise FlowingError("This operation is not RPython") def BREAK_LOOP(self, oparg): - return SBreakLoop.singleton.unroll(self) + return self.unroll(SBreakLoop.singleton) def CONTINUE_LOOP(self, startofloop): - unroller = SContinueLoop(startofloop) - return unroller.unroll(self) + return self.unroll(SContinueLoop(startofloop)) def cmp_lt(self, w_1, w_2): return self.space.lt(w_1, w_2) @@ -674,8 +681,7 @@ def RETURN_VALUE(self, oparg): w_returnvalue = self.popvalue() - unroller = SReturnValue(w_returnvalue) - return unroller.unroll(self) + return self.unroll(SReturnValue(w_returnvalue)) def END_FINALLY(self, oparg): # unlike CPython, there are two statically distinct cases: the @@ -683,22 +689,22 @@ # block. In the first case, the stack contains three items: # [exception type we are now handling] # [exception value we are now handling] - # [wrapped SApplicationException] + # [SApplicationException] # In the case of a finally: block, the stack contains only one # item (unlike CPython which can have 1, 2 or 3 items): - # [wrapped subclass of SuspendedUnroller] + # [wrapped subclass of FlowSignal] w_top = self.popvalue() if w_top == self.space.w_None: # finally: block with no unroller active return - elif isinstance(w_top, SuspendedUnroller): + elif isinstance(w_top, FlowSignal): # case of a finally: block - return w_top.unroll(self) + return self.unroll(w_top) else: # case of an except: block. We popped the exception type self.popvalue() # Now we pop the exception value - unroller = self.popvalue() - return unroller.unroll(self) + signal = self.popvalue() + return self.unroll(signal) def POP_BLOCK(self, oparg): block = self.blockstack.pop() @@ -1126,10 +1132,9 @@ ### Frame blocks ### -class SuspendedUnroller(object): - """Abstract base class for interpreter-level objects that - instruct the interpreter to change the control flow and the - block stack. +class FlowSignal(object): + """Abstract base class for translator-level objects that instruct the + interpreter to change the control flow and the block stack. The concrete subclasses correspond to the various values WHY_XXX values of the why_code enumeration in ceval.c: @@ -1142,22 +1147,11 @@ WHY_CONTINUE, SContinueLoop WHY_YIELD not needed """ - def unroll(self, frame): - while frame.blockstack: - block = frame.blockstack.pop() - if isinstance(self, block.handles): - return block.handle(frame, self) - block.cleanupstack(frame) - return self.nomoreblocks() - def nomoreblocks(self): raise BytecodeCorruption("misplaced bytecode - should not return") - # NB. for the flow object space, the state_(un)pack_variables methods - # give a way to "pickle" and "unpickle" the SuspendedUnroller by - # enumerating the Variables it contains. -class SReturnValue(SuspendedUnroller): +class SReturnValue(FlowSignal): """Signals a 'return' statement. Argument is the wrapped object to return.""" @@ -1174,7 +1168,7 @@ def state_pack_variables(w_returnvalue): return SReturnValue(w_returnvalue) -class SApplicationException(SuspendedUnroller): +class SApplicationException(FlowSignal): """Signals an application-level exception (i.e. an OperationException).""" @@ -1196,7 +1190,7 @@ def nomoreblocks(self): raise RaiseImplicit(self.operr) -class SBreakLoop(SuspendedUnroller): +class SBreakLoop(FlowSignal): """Signals a 'break' statement.""" def state_unpack_variables(self): @@ -1208,7 +1202,7 @@ SBreakLoop.singleton = SBreakLoop() -class SContinueLoop(SuspendedUnroller): +class SContinueLoop(FlowSignal): """Signals a 'continue' statement. Argument is the bytecode position of the beginning of the loop.""" @@ -1288,7 +1282,7 @@ class FinallyBlock(FrameBlock): """A try:finally: block. Stores the position of the exception handler.""" - handles = SuspendedUnroller + handles = FlowSignal def handle(self, frame, unroller): # any abnormal reason for unrolling a finally: triggers the end of diff --git a/rpython/flowspace/framestate.py b/rpython/flowspace/framestate.py --- a/rpython/flowspace/framestate.py +++ b/rpython/flowspace/framestate.py @@ -74,7 +74,7 @@ if isinstance(w1, Constant) and isinstance(w2, Constant): if w1 == w2: return w1 - # SuspendedUnrollers represent stack unrollers in the stack. + # FlowSignal represent stack unrollers in the stack. # They should not be merged because they will be unwrapped. # This is needed for try:except: and try:finally:, though # it makes the control flow a bit larger by duplicating the @@ -94,7 +94,7 @@ # We have to flatten out the state of the frame into a list of # Variables and Constants. This is done above by collecting the # locals and the items on the value stack, but the latter may contain -# SuspendedUnroller. We have to handle these specially, because +# FlowSignal. We have to handle these specially, because # some of them hide references to more Variables and Constants. # The trick is to flatten ("pickle") them into the list so that the # extra Variables show up directly in the list too. @@ -107,11 +107,11 @@ def recursively_flatten(lst): - from rpython.flowspace.flowcontext import SuspendedUnroller + from rpython.flowspace.flowcontext import FlowSignal i = 0 while i < len(lst): unroller = lst[i] - if not isinstance(unroller, SuspendedUnroller): + if not isinstance(unroller, FlowSignal): i += 1 else: vars = unroller.state_unpack_variables() From noreply at buildbot.pypy.org Sun Sep 8 18:28:35 2013 From: noreply at buildbot.pypy.org (rlamy) Date: Sun, 8 Sep 2013 18:28:35 +0200 (CEST) Subject: [pypy-commit] pypy less-stringly-ops: Merge Return/Raise exceptions with FlowSignal classes Message-ID: <20130908162835.4EFD31C0315@cobra.cs.uni-duesseldorf.de> Author: Ronan Lamy Branch: less-stringly-ops Changeset: r66849:e48d83d9c9f0 Date: 2013-09-08 17:27 +0100 http://bitbucket.org/pypy/pypy/changeset/e48d83d9c9f0/ Log: Merge Return/Raise exceptions with FlowSignal classes diff --git a/rpython/flowspace/flowcontext.py b/rpython/flowspace/flowcontext.py --- a/rpython/flowspace/flowcontext.py +++ b/rpython/flowspace/flowcontext.py @@ -30,17 +30,6 @@ class StopFlowing(Exception): pass -class Return(Exception): - def __init__(self, value): - self.value = value - -class Raise(Exception): - def __init__(self, value): - self.value = value - -class RaiseImplicit(Raise): - pass - class BytecodeCorruption(Exception): pass @@ -478,7 +467,7 @@ self.recorder.final_state = self.getstate(next_pos) except RaiseImplicit as e: - w_exc = e.value + w_exc = e.operr if isinstance(w_exc.w_type, Constant): exc_cls = w_exc.w_type.value else: @@ -490,7 +479,7 @@ self.recorder.crnt_block.closeblock(link) except Raise as e: - w_exc = e.value + w_exc = e.operr if w_exc.w_type == self.space.w_ImportError: msg = 'import statement always raises %s' % e raise ImportError(msg) @@ -501,7 +490,7 @@ pass except Return as exc: - w_result = exc.value + w_result = exc.w_returnvalue link = Link([w_result], self.graph.returnblock) self.recorder.crnt_block.closeblock(link) @@ -568,10 +557,8 @@ try: res = getattr(self, methodname)(oparg) return res if res is not None else next_instr - except RaiseImplicit as e: - return self.unroll(SImplicitException(e.value)) except Raise as e: - return self.unroll(SApplicationException(e.value)) + return self.unroll(e) def unroll(self, signal): while self.blockstack: @@ -681,7 +668,7 @@ def RETURN_VALUE(self, oparg): w_returnvalue = self.popvalue() - return self.unroll(SReturnValue(w_returnvalue)) + return self.unroll(Return(w_returnvalue)) def END_FINALLY(self, oparg): # unlike CPython, there are two statically distinct cases: the @@ -689,7 +676,7 @@ # block. In the first case, the stack contains three items: # [exception type we are now handling] # [exception value we are now handling] - # [SApplicationException] + # [Raise] # In the case of a finally: block, the stack contains only one # item (unlike CPython which can have 1, 2 or 3 items): # [wrapped subclass of FlowSignal] @@ -783,7 +770,7 @@ try: w_nextitem = self.space.next(w_iterator) except Raise as e: - w_exc = e.value + w_exc = e.operr if not self.space.exception_match(w_exc.w_type, self.space.w_StopIteration): raise @@ -830,7 +817,7 @@ unroller = self.peekvalue(0) w_None = self.space.w_None - if isinstance(unroller, SApplicationException): + if isinstance(unroller, Raise): operr = unroller.operr # The annotator won't allow to merge exception types with None. # Replace it with the exception value... @@ -1132,7 +1119,7 @@ ### Frame blocks ### -class FlowSignal(object): +class FlowSignal(Exception): """Abstract base class for translator-level objects that instruct the interpreter to change the control flow and the block stack. @@ -1140,9 +1127,9 @@ values of the why_code enumeration in ceval.c: WHY_NOT, OK, not this one :-) - WHY_EXCEPTION, SApplicationException + WHY_EXCEPTION, Raise WHY_RERAISE, implemented differently, see Reraise - WHY_RETURN, SReturnValue + WHY_RETURN, Return WHY_BREAK, SBreakLoop WHY_CONTINUE, SContinueLoop WHY_YIELD not needed @@ -1151,7 +1138,7 @@ raise BytecodeCorruption("misplaced bytecode - should not return") -class SReturnValue(FlowSignal): +class Return(FlowSignal): """Signals a 'return' statement. Argument is the wrapped object to return.""" @@ -1166,9 +1153,9 @@ @staticmethod def state_pack_variables(w_returnvalue): - return SReturnValue(w_returnvalue) + return Return(w_returnvalue) -class SApplicationException(FlowSignal): +class Raise(FlowSignal): """Signals an application-level exception (i.e. an OperationException).""" @@ -1176,19 +1163,18 @@ self.operr = operr def nomoreblocks(self): - raise Raise(self.operr) + raise self def state_unpack_variables(self): return [self.operr.w_type, self.operr.w_value] @staticmethod def state_pack_variables(w_type, w_value): - return SApplicationException(FSException(w_type, w_value)) + return Raise(FSException(w_type, w_value)) -class SImplicitException(SApplicationException): +class RaiseImplicit(Raise): """Signals an exception raised implicitly""" - def nomoreblocks(self): - raise RaiseImplicit(self.operr) + class SBreakLoop(FlowSignal): """Signals a 'break' statement.""" @@ -1262,13 +1248,13 @@ class ExceptBlock(FrameBlock): """An try:except: block. Stores the position of the exception handler.""" - handles = SApplicationException + handles = Raise def handle(self, frame, unroller): # push the exception to the value stack for inspection by the # exception handler (the code after the except:) self.cleanupstack(frame) - assert isinstance(unroller, SApplicationException) + assert isinstance(unroller, Raise) operationerr = unroller.operr # the stack setup is slightly different than in CPython: # instead of the traceback, we store the unroller object, From noreply at buildbot.pypy.org Sun Sep 8 19:48:50 2013 From: noreply at buildbot.pypy.org (rlamy) Date: Sun, 8 Sep 2013 19:48:50 +0200 (CEST) Subject: [pypy-commit] pypy less-stringly-ops: Handle FlowSignals more consistently Message-ID: <20130908174850.525461C12DA@cobra.cs.uni-duesseldorf.de> Author: Ronan Lamy Branch: less-stringly-ops Changeset: r66850:c51af2d7848d Date: 2013-09-08 18:48 +0100 http://bitbucket.org/pypy/pypy/changeset/c51af2d7848d/ Log: Handle FlowSignals more consistently diff --git a/rpython/flowspace/flowcontext.py b/rpython/flowspace/flowcontext.py --- a/rpython/flowspace/flowcontext.py +++ b/rpython/flowspace/flowcontext.py @@ -467,7 +467,7 @@ self.recorder.final_state = self.getstate(next_pos) except RaiseImplicit as e: - w_exc = e.operr + w_exc = e.w_exc if isinstance(w_exc.w_type, Constant): exc_cls = w_exc.w_type.value else: @@ -479,7 +479,7 @@ self.recorder.crnt_block.closeblock(link) except Raise as e: - w_exc = e.operr + w_exc = e.w_exc if w_exc.w_type == self.space.w_ImportError: msg = 'import statement always raises %s' % e raise ImportError(msg) @@ -490,7 +490,7 @@ pass except Return as exc: - w_result = exc.w_returnvalue + w_result = exc.w_value link = Link([w_result], self.graph.returnblock) self.recorder.crnt_block.closeblock(link) @@ -557,8 +557,8 @@ try: res = getattr(self, methodname)(oparg) return res if res is not None else next_instr - except Raise as e: - return self.unroll(e) + except FlowSignal as signal: + return self.unroll(signal) def unroll(self, signal): while self.blockstack: @@ -584,10 +584,10 @@ raise FlowingError("This operation is not RPython") def BREAK_LOOP(self, oparg): - return self.unroll(SBreakLoop.singleton) + raise Break def CONTINUE_LOOP(self, startofloop): - return self.unroll(SContinueLoop(startofloop)) + raise Continue(startofloop) def cmp_lt(self, w_1, w_2): return self.space.lt(w_1, w_2) @@ -668,7 +668,7 @@ def RETURN_VALUE(self, oparg): w_returnvalue = self.popvalue() - return self.unroll(Return(w_returnvalue)) + raise Return(w_returnvalue) def END_FINALLY(self, oparg): # unlike CPython, there are two statically distinct cases: the @@ -679,19 +679,19 @@ # [Raise] # In the case of a finally: block, the stack contains only one # item (unlike CPython which can have 1, 2 or 3 items): - # [wrapped subclass of FlowSignal] + # [subclass of FlowSignal] w_top = self.popvalue() if w_top == self.space.w_None: # finally: block with no unroller active return elif isinstance(w_top, FlowSignal): # case of a finally: block - return self.unroll(w_top) + raise w_top else: # case of an except: block. We popped the exception type self.popvalue() # Now we pop the exception value signal = self.popvalue() - return self.unroll(signal) + raise signal def POP_BLOCK(self, oparg): block = self.blockstack.pop() @@ -770,7 +770,7 @@ try: w_nextitem = self.space.next(w_iterator) except Raise as e: - w_exc = e.operr + w_exc = e.w_exc if not self.space.exception_match(w_exc.w_type, self.space.w_StopIteration): raise @@ -818,11 +818,11 @@ w_None = self.space.w_None if isinstance(unroller, Raise): - operr = unroller.operr + w_exc = unroller.w_exc # The annotator won't allow to merge exception types with None. # Replace it with the exception value... self.space.call_function(w_exitfunc, - operr.w_value, operr.w_value, w_None) + w_exc.w_value, w_exc.w_value, w_None) else: self.space.call_function(w_exitfunc, w_None, w_None, w_None) @@ -1130,8 +1130,8 @@ WHY_EXCEPTION, Raise WHY_RERAISE, implemented differently, see Reraise WHY_RETURN, Return - WHY_BREAK, SBreakLoop - WHY_CONTINUE, SContinueLoop + WHY_BREAK, Break + WHY_CONTINUE, Continue WHY_YIELD not needed """ def nomoreblocks(self): @@ -1142,31 +1142,31 @@ """Signals a 'return' statement. Argument is the wrapped object to return.""" - def __init__(self, w_returnvalue): - self.w_returnvalue = w_returnvalue + def __init__(self, w_value): + self.w_value = w_value def nomoreblocks(self): - raise Return(self.w_returnvalue) + raise Return(self.w_value) def state_unpack_variables(self): - return [self.w_returnvalue] + return [self.w_value] @staticmethod - def state_pack_variables(w_returnvalue): - return Return(w_returnvalue) + def state_pack_variables(w_value): + return Return(w_value) class Raise(FlowSignal): """Signals an application-level exception (i.e. an OperationException).""" - def __init__(self, operr): - self.operr = operr + def __init__(self, w_exc): + self.w_exc = w_exc def nomoreblocks(self): raise self def state_unpack_variables(self): - return [self.operr.w_type, self.operr.w_value] + return [self.w_exc.w_type, self.w_exc.w_value] @staticmethod def state_pack_variables(w_type, w_value): @@ -1176,7 +1176,7 @@ """Signals an exception raised implicitly""" -class SBreakLoop(FlowSignal): +class Break(FlowSignal): """Signals a 'break' statement.""" def state_unpack_variables(self): @@ -1184,11 +1184,11 @@ @staticmethod def state_pack_variables(): - return SBreakLoop.singleton + return Break.singleton -SBreakLoop.singleton = SBreakLoop() +Break.singleton = Break() -class SContinueLoop(FlowSignal): +class Continue(FlowSignal): """Signals a 'continue' statement. Argument is the bytecode position of the beginning of the loop.""" @@ -1200,7 +1200,7 @@ @staticmethod def state_pack_variables(w_jump_to): - return SContinueLoop(w_jump_to.value) + return Continue(w_jump_to.value) class FrameBlock(object): @@ -1231,10 +1231,10 @@ class LoopBlock(FrameBlock): """A loop block. Stores the end-of-loop pointer in case of 'break'.""" - handles = (SBreakLoop, SContinueLoop) + handles = (Break, Continue) def handle(self, frame, unroller): - if isinstance(unroller, SContinueLoop): + if isinstance(unroller, Continue): # re-push the loop block without cleaning up the value stack, # and jump to the beginning of the loop, stored in the # exception's argument @@ -1255,14 +1255,14 @@ # exception handler (the code after the except:) self.cleanupstack(frame) assert isinstance(unroller, Raise) - operationerr = unroller.operr + w_exc = unroller.w_exc # the stack setup is slightly different than in CPython: # instead of the traceback, we store the unroller object, # wrapped. frame.pushvalue(unroller) - frame.pushvalue(operationerr.w_value) - frame.pushvalue(operationerr.w_type) - frame.last_exception = operationerr + frame.pushvalue(w_exc.w_value) + frame.pushvalue(w_exc.w_type) + frame.last_exception = w_exc return self.handlerposition # jump to the handler class FinallyBlock(FrameBlock): From noreply at buildbot.pypy.org Sun Sep 8 20:00:02 2013 From: noreply at buildbot.pypy.org (bivab) Date: Sun, 8 Sep 2013 20:00:02 +0200 (CEST) Subject: [pypy-commit] buildbot default: store the original revsion and eventually set the final_file_name in the parse_revision step Message-ID: <20130908180002.843FB1C12F0@cobra.cs.uni-duesseldorf.de> Author: David Schneider Branch: Changeset: r861:098f9a97951d Date: 2013-09-08 19:58 +0200 http://bitbucket.org/pypy/buildbot/changeset/098f9a97951d/ Log: store the original revsion and eventually set the final_file_name in the parse_revision step diff --git a/bot2/pypybuildbot/builds.py b/bot2/pypybuildbot/builds.py --- a/bot2/pypybuildbot/builds.py +++ b/bot2/pypybuildbot/builds.py @@ -203,8 +203,9 @@ # ':' should not be part of filenames --- too many issues self.build.setProperty('got_revision', got_revision, 'got_revision') - self.build.setProperty('final_file_name', final_file_name, - 'got_revision') + if not self.build.hasProperty('final_file_name'): + self.build.setProperty('final_file_name', final_file_name, + 'got_revision') class ParseRevision(BuildStep): """Parse the revision property of the source stamp and extract the global @@ -226,12 +227,20 @@ def start(self): stamp = self.build.getSourceStamp() - revision = stamp.revision - if isinstance(revision, (unicode, str)) and ':' in revision: - parts = revision.split(':') - self.build.setProperty('revision', parts[1], 'parse_revision') - stamp.revision = parts[1] - self.finished(SUCCESS) + revision = stamp.revision if stamp.revision is not None else '' + # + if not isinstance(revision, (unicode, str)) or ":" not in revision: + self.finished(SKIPPED) + return + # + self.build.setProperty('original_revision', revision, 'parse_revision') + self.build.setProperty('final_file_name', + revision.replace(':', '-'), 'parse_revision') + # + parts = revision.split(':') + self.build.setProperty('revision', parts[1], 'parse_revision') + stamp.revision = parts[1] + self.finished(SUCCESS) def update_hg(platform, factory, repourl, workdir, use_branch, diff --git a/bot2/pypybuildbot/test/test_builds.py b/bot2/pypybuildbot/test/test_builds.py --- a/bot2/pypybuildbot/test/test_builds.py +++ b/bot2/pypybuildbot/test/test_builds.py @@ -192,6 +192,8 @@ self.rebuilt.build = FakeBuild({'revision':u'123:ea5ca8'}) self.rebuilt.start() assert self.rebuilt.build.getProperties()['revision'] == 'ea5ca8' + assert self.rebuilt.build.getProperties()['original_revision'] == '123:ea5ca8' + assert self.rebuilt.build.getProperties()['final_file_name'] == '123-ea5ca8' def test_no_revision(self): self.rebuilt.build = FakeBuild() From noreply at buildbot.pypy.org Sun Sep 8 20:00:03 2013 From: noreply at buildbot.pypy.org (bivab) Date: Sun, 8 Sep 2013 20:00:03 +0200 (CEST) Subject: [pypy-commit] buildbot default: use the final_file_name property to build the URL to download a build Message-ID: <20130908180003.7FDCF1C12F0@cobra.cs.uni-duesseldorf.de> Author: David Schneider Branch: Changeset: r862:212f98def1ce Date: 2013-09-08 19:59 +0200 http://bitbucket.org/pypy/buildbot/changeset/212f98def1ce/ Log: use the final_file_name property to build the URL to download a build diff --git a/bot2/pypybuildbot/builds.py b/bot2/pypybuildbot/builds.py --- a/bot2/pypybuildbot/builds.py +++ b/bot2/pypybuildbot/builds.py @@ -85,7 +85,7 @@ properties = self.build.getProperties() branch = map_branch_name(properties['branch']) - revision = properties['revision'] + revision = properties['final_file_name'] mastersrc = os.path.expanduser(self.mastersrc) if branch.startswith('/'): @@ -95,7 +95,7 @@ basename = WithProperties(self.basename).getRenderingFor(self.build) basename = basename.replace(':', '-') else: - basename = self.basename.replace('%(revision)s', 'latest') + basename = self.basename.replace('%(final_file_name)s', 'latest') assert '%' not in basename self.mastersrc = os.path.join(mastersrc, basename) @@ -454,7 +454,7 @@ command=['rm', '-rf', 'pypy-c'], workdir='.')) extension = get_extension(platform) - name = build_name(platform, pypyjit, translationArgs, placeholder='%(revision)s') + extension + name = build_name(platform, pypyjit, translationArgs, placeholder='%(final_file_name)s') + extension self.addStep(PyPyDownload( basename=name, mastersrc='~/nightly', From noreply at buildbot.pypy.org Sun Sep 8 21:49:40 2013 From: noreply at buildbot.pypy.org (amauryfa) Date: Sun, 8 Sep 2013 21:49:40 +0200 (CEST) Subject: [pypy-commit] pypy default: Add support for TCL libraries compiled with --disable-threads. Message-ID: <20130908194940.E26611C136D@cobra.cs.uni-duesseldorf.de> Author: Amaury Forgeot d'Arc Branch: Changeset: r66851:a2cfb94ccff5 Date: 2013-09-08 21:47 +0200 http://bitbucket.org/pypy/pypy/changeset/a2cfb94ccff5/ Log: Add support for TCL libraries compiled with --disable-threads. (manually tested with a custom build of TCL) diff --git a/lib_pypy/_tkinter/__init__.py b/lib_pypy/_tkinter/__init__.py --- a/lib_pypy/_tkinter/__init__.py +++ b/lib_pypy/_tkinter/__init__.py @@ -22,6 +22,7 @@ READABLE = tklib.TCL_READABLE WRITABLE = tklib.TCL_WRITABLE EXCEPTION = tklib.TCL_EXCEPTION +DONT_WAIT = tklib.TCL_DONT_WAIT def create(screenName=None, baseName=None, className=None, interactive=False, wantobjects=False, wantTk=True, diff --git a/lib_pypy/_tkinter/app.py b/lib_pypy/_tkinter/app.py --- a/lib_pypy/_tkinter/app.py +++ b/lib_pypy/_tkinter/app.py @@ -4,7 +4,23 @@ from . import TclError from .tclobj import TclObject, FromObj, AsObj, TypeCache +import contextlib import sys +import threading +import time + + +class _DummyLock(object): + "A lock-like object that does not do anything" + def acquire(self): + pass + def release(self): + pass + def __enter__(self): + pass + def __exit__(self, *exc): + pass + def varname_converter(input): if isinstance(input, TclObject): @@ -37,17 +53,18 @@ def PythonCmd(clientData, interp, argc, argv): self = tkffi.from_handle(clientData) assert self.app.interp == interp - try: - args = [tkffi.string(arg) for arg in argv[1:argc]] - result = self.func(*args) - obj = AsObj(result) - tklib.Tcl_SetObjResult(interp, obj) - except: - self.app.errorInCmd = True - self.app.exc_info = sys.exc_info() - return tklib.TCL_ERROR - else: - return tklib.TCL_OK + with self.app._tcl_lock_released(): + try: + args = [tkffi.string(arg) for arg in argv[1:argc]] + result = self.func(*args) + obj = AsObj(result) + tklib.Tcl_SetObjResult(interp, obj) + except: + self.app.errorInCmd = True + self.app.exc_info = sys.exc_info() + return tklib.TCL_ERROR + else: + return tklib.TCL_OK @tkffi.callback("Tcl_CmdDeleteProc") def PythonCmdDelete(clientData): @@ -58,6 +75,8 @@ class TkApp(object): + _busywaitinterval = 0.02 # 20ms. + def __new__(cls, screenName, baseName, className, interactive, wantobjects, wantTk, sync, use): if not wantobjects: @@ -73,6 +92,12 @@ self.quitMainLoop = False self.errorInCmd = False + if not self.threaded: + # TCL is not thread-safe, calls needs to be serialized. + self._tcl_lock = threading.Lock() + else: + self._tcl_lock = _DummyLock() + self._typeCache = TypeCache() self._commands = {} @@ -133,6 +158,13 @@ if self.threaded and self.thread_id != tklib.Tcl_GetCurrentThread(): raise RuntimeError("Calling Tcl from different appartment") + @contextlib.contextmanager + def _tcl_lock_released(self): + "Context manager to temporarily release the tcl lock." + self._tcl_lock.release() + yield + self._tcl_lock.acquire() + def loadtk(self): # We want to guard against calling Tk_Init() multiple times err = tklib.Tcl_Eval(self.interp, "info exists tk_version") @@ -159,22 +191,25 @@ flags=tklib.TCL_LEAVE_ERR_MSG if global_only: flags |= tklib.TCL_GLOBAL_ONLY - res = tklib.Tcl_GetVar2Ex(self.interp, name1, name2, flags) - if not res: - self.raiseTclError() - assert self._wantobjects - return FromObj(self, res) + with self._tcl_lock: + res = tklib.Tcl_GetVar2Ex(self.interp, name1, name2, flags) + if not res: + self.raiseTclError() + assert self._wantobjects + return FromObj(self, res) def _setvar(self, name1, value, global_only=False): name1 = varname_converter(name1) + # XXX Acquire tcl lock??? newval = AsObj(value) flags=tklib.TCL_LEAVE_ERR_MSG if global_only: flags |= tklib.TCL_GLOBAL_ONLY - res = tklib.Tcl_SetVar2Ex(self.interp, name1, tkffi.NULL, - newval, flags) - if not res: - self.raiseTclError() + with self._tcl_lock: + res = tklib.Tcl_SetVar2Ex(self.interp, name1, tkffi.NULL, + newval, flags) + if not res: + self.raiseTclError() def _unsetvar(self, name1, name2=None, global_only=False): name1 = varname_converter(name1) @@ -183,9 +218,10 @@ flags=tklib.TCL_LEAVE_ERR_MSG if global_only: flags |= tklib.TCL_GLOBAL_ONLY - res = tklib.Tcl_UnsetVar2(self.interp, name1, name2, flags) - if res == tklib.TCL_ERROR: - self.raiseTclError() + with self._tcl_lock: + res = tklib.Tcl_UnsetVar2(self.interp, name1, name2, flags) + if res == tklib.TCL_ERROR: + self.raiseTclError() def getvar(self, name1, name2=None): return self._var_invoke(self._getvar, name1, name2) @@ -219,9 +255,10 @@ if self.threaded and self.thread_id != tklib.Tcl_GetCurrentThread(): raise NotImplementedError("Call from another thread") - res = tklib.Tcl_CreateCommand( - self.interp, cmdName, _CommandData.PythonCmd, - clientData, _CommandData.PythonCmdDelete) + with self._tcl_lock: + res = tklib.Tcl_CreateCommand( + self.interp, cmdName, _CommandData.PythonCmd, + clientData, _CommandData.PythonCmdDelete) if not res: raise TclError("can't create Tcl command") @@ -229,7 +266,8 @@ if self.threaded and self.thread_id != tklib.Tcl_GetCurrentThread(): raise NotImplementedError("Call from another thread") - res = tklib.Tcl_DeleteCommand(self.interp, cmdName) + with self._tcl_lock: + res = tklib.Tcl_DeleteCommand(self.interp, cmdName) if res == -1: raise TclError("can't delete Tcl command") @@ -256,11 +294,12 @@ tklib.Tcl_IncrRefCount(obj) objects[i] = obj - res = tklib.Tcl_EvalObjv(self.interp, argc, objects, flags) - if res == tklib.TCL_ERROR: - self.raiseTclError() - else: - result = self._callResult() + with self._tcl_lock: + res = tklib.Tcl_EvalObjv(self.interp, argc, objects, flags) + if res == tklib.TCL_ERROR: + self.raiseTclError() + else: + result = self._callResult() finally: for obj in objects: if obj: @@ -280,17 +319,19 @@ def eval(self, script): self._check_tcl_appartment() - res = tklib.Tcl_Eval(self.interp, script) - if res == tklib.TCL_ERROR: - self.raiseTclError() - return tkffi.string(tklib.Tcl_GetStringResult(self.interp)) + with self._tcl_lock: + res = tklib.Tcl_Eval(self.interp, script) + if res == tklib.TCL_ERROR: + self.raiseTclError() + return tkffi.string(tklib.Tcl_GetStringResult(self.interp)) def evalfile(self, filename): self._check_tcl_appartment() - res = tklib.Tcl_EvalFile(self.interp, filename) - if res == tklib.TCL_ERROR: - self.raiseTclError() - return tkffi.string(tklib.Tcl_GetStringResult(self.interp)) + with self._tcl_lock: + res = tklib.Tcl_EvalFile(self.interp, filename) + if res == tklib.TCL_ERROR: + self.raiseTclError() + return tkffi.string(tklib.Tcl_GetStringResult(self.interp)) def split(self, arg): if isinstance(arg, tuple): @@ -375,7 +416,10 @@ if self.threaded: result = tklib.Tcl_DoOneEvent(0) else: - raise NotImplementedError("TCL configured without threads") + with self._tcl_lock: + result = tklib.Tcl_DoOneEvent(tklib.TCL_DONT_WAIT) + if result == 0: + time.sleep(self._busywaitinterval) if result < 0: break diff --git a/lib_pypy/_tkinter/tklib.py b/lib_pypy/_tkinter/tklib.py --- a/lib_pypy/_tkinter/tklib.py +++ b/lib_pypy/_tkinter/tklib.py @@ -19,6 +19,8 @@ #define TCL_EVAL_DIRECT ... #define TCL_EVAL_GLOBAL ... +#define TCL_DONT_WAIT ... + typedef unsigned short Tcl_UniChar; typedef ... Tcl_Interp; typedef ...* Tcl_ThreadId; From noreply at buildbot.pypy.org Mon Sep 9 00:05:14 2013 From: noreply at buildbot.pypy.org (mattip) Date: Mon, 9 Sep 2013 00:05:14 +0200 (CEST) Subject: [pypy-commit] pypy pypy-pyarray: remove finished task from TODO.txt Message-ID: <20130908220514.60D501C12EC@cobra.cs.uni-duesseldorf.de> Author: Matti Picus Branch: pypy-pyarray Changeset: r66853:8501a3de2e2e Date: 2013-09-04 16:38 +0300 http://bitbucket.org/pypy/pypy/changeset/8501a3de2e2e/ Log: remove finished task from TODO.txt diff --git a/TODO.txt b/TODO.txt --- a/TODO.txt +++ b/TODO.txt @@ -4,17 +4,6 @@ - why do we need to implement array.nonzero on this branch and it was not done e.g. on default? -- in cpyext/ndarrayobject.py: most functions starts with code like this: - - @cpython_api([PyObject], rffi.INT_real, error=CANNOT_FAIL) - def _PyArray_FLAGS(space, w_array): - assert isinstance(w_array, W_NDimArray) - ... - - this is very bad because if you pass something which is not a numpy array, - you get an RPython AssertionError instead of a nice applevel TypeError - - - def _PyArray_FromAny(space, w_obj, dtype, min_depth, max_depth, requirements, context): # ignore all additional arguments for now From noreply at buildbot.pypy.org Mon Sep 9 00:05:15 2013 From: noreply at buildbot.pypy.org (mattip) Date: Mon, 9 Sep 2013 00:05:15 +0200 (CEST) Subject: [pypy-commit] pypy pypy-pyarray: raise exceptions on invalid or non-implemented args, try harder to catch invalid args Message-ID: <20130908220515.9BF971C12F0@cobra.cs.uni-duesseldorf.de> Author: Matti Picus Branch: pypy-pyarray Changeset: r66854:3d8f4373ec61 Date: 2013-09-08 23:04 +0200 http://bitbucket.org/pypy/pypy/changeset/3d8f4373ec61/ Log: raise exceptions on invalid or non-implemented args, try harder to catch invalid args diff --git a/pypy/module/cpyext/api.py b/pypy/module/cpyext/api.py --- a/pypy/module/cpyext/api.py +++ b/pypy/module/cpyext/api.py @@ -159,7 +159,7 @@ numpy_headers = numpy_include_dir.listdir('*.h') + numpy_include_dir.listdir('*.inl') _copy_header_files(numpy_headers, numpy_dstdir) - + class NotSpecified(object): pass _NOT_SPECIFIED = NotSpecified() @@ -303,9 +303,23 @@ elif isinstance(input_arg, W_Root): arg = input_arg else: - arg = from_ref(space, + try: + arg = from_ref(space, rffi.cast(PyObject, input_arg)) + except TypeError, e: + err = OperationError(space.w_TypeError, + space.wrap( + "could not cast arg to PyObject")) + if not catch_exception: + raise err + state = space.fromcache(State) + state.set_exception(err) + if is_PyObject(restype): + return None + else: + return api_function.error_value else: + # convert to a wrapped object arg = input_arg newargs += (arg, ) try: @@ -403,13 +417,13 @@ 'PyStructSequence_InitType', 'PyStructSequence_New', 'PyFunction_Type', 'PyMethod_Type', 'PyRange_Type', 'PyTraceBack_Type', - + 'PyArray_Type', '_PyArray_FILLWBYTE', '_PyArray_ZEROS', '_PyArray_CopyInto', 'Py_DebugFlag', 'Py_VerboseFlag', 'Py_InteractiveFlag', 'Py_InspectFlag', - 'Py_OptimizeFlag', 'Py_NoSiteFlag', 'Py_BytesWarningFlag', 'Py_UseClassExceptionsFlag', - 'Py_FrozenFlag', 'Py_TabcheckFlag', 'Py_UnicodeFlag', 'Py_IgnoreEnvironmentFlag', - 'Py_DivisionWarningFlag', 'Py_DontWriteBytecodeFlag', 'Py_NoUserSiteDirectory', + 'Py_OptimizeFlag', 'Py_NoSiteFlag', 'Py_BytesWarningFlag', 'Py_UseClassExceptionsFlag', + 'Py_FrozenFlag', 'Py_TabcheckFlag', 'Py_UnicodeFlag', 'Py_IgnoreEnvironmentFlag', + 'Py_DivisionWarningFlag', 'Py_DontWriteBytecodeFlag', 'Py_NoUserSiteDirectory', '_Py_QnewFlag', 'Py_Py3kWarningFlag', 'Py_HashRandomizationFlag', '_Py_PackageContext', ] TYPES = {} diff --git a/pypy/module/cpyext/ndarrayobject.py b/pypy/module/cpyext/ndarrayobject.py --- a/pypy/module/cpyext/ndarrayobject.py +++ b/pypy/module/cpyext/ndarrayobject.py @@ -60,7 +60,7 @@ @cpython_api([PyObject], rffi.INT_real, error=-1) def _PyArray_FLAGS(space, w_array): if not isinstance(w_array, W_NDimArray): - raise OperationError(space.w_ValueError, space.wrap( + raise OperationError(space.w_TypeError, space.wrap( '_PyArray_FLAGS(ndarray) called with non-ndarray')) flags = NPY_BEHAVED_NS if isinstance(w_array.implementation, ConcreteArray): @@ -76,49 +76,49 @@ @cpython_api([PyObject], rffi.INT_real, error=-1) def _PyArray_NDIM(space, w_array): if not isinstance(w_array, W_NDimArray): - raise OperationError(space.w_ValueError, space.wrap( + raise OperationError(space.w_TypeError, space.wrap( '_PyArray_NDIM(ndarray) called with non-ndarray')) return len(w_array.get_shape()) @cpython_api([PyObject, Py_ssize_t], Py_ssize_t, error=-1) def _PyArray_DIM(space, w_array, n): if not isinstance(w_array, W_NDimArray): - raise OperationError(space.w_ValueError, space.wrap( + raise OperationError(space.w_TypeError, space.wrap( '_PyArray_DIM called with non-ndarray')) return w_array.get_shape()[n] @cpython_api([PyObject, Py_ssize_t], Py_ssize_t, error=-1) def _PyArray_STRIDE(space, w_array, n): if not isinstance(w_array, W_NDimArray): - raise OperationError(space.w_ValueError, space.wrap( + raise OperationError(space.w_TypeError, space.wrap( '_PyArray_STRIDE called with non-ndarray')) return w_array.implementation.get_strides()[n] @cpython_api([PyObject], Py_ssize_t, error=-1) def _PyArray_SIZE(space, w_array): if not isinstance(w_array, W_NDimArray): - raise OperationError(space.w_ValueError, space.wrap( + raise OperationError(space.w_TypeError, space.wrap( '_PyArray_SIZE called with non-ndarray')) return w_array.get_size() @cpython_api([PyObject], rffi.INT_real, error=-1) def _PyArray_ITEMSIZE(space, w_array): if not isinstance(w_array, W_NDimArray): - raise OperationError(space.w_ValueError, space.wrap( + raise OperationError(space.w_TypeError, space.wrap( '_PyArray_ITEMSIZE called with non-ndarray')) return w_array.get_dtype().get_size() @cpython_api([PyObject], Py_ssize_t, error=-1) def _PyArray_NBYTES(space, w_array): if not isinstance(w_array, W_NDimArray): - raise OperationError(space.w_ValueError, space.wrap( + raise OperationError(space.w_TypeError, space.wrap( '_PyArray_NBYTES called with non-ndarray')) return w_array.get_size() * w_array.get_dtype().get_size() @cpython_api([PyObject], rffi.INT_real, error=-1) def _PyArray_TYPE(space, w_array): if not isinstance(w_array, W_NDimArray): - raise OperationError(space.w_ValueError, space.wrap( + raise OperationError(space.w_TypeError, space.wrap( '_PyArray_TYPE called with non-ndarray')) return w_array.get_dtype().num @@ -127,15 +127,53 @@ def _PyArray_DATA(space, w_array): # fails on scalars - see PyArray_FromAny() if not isinstance(w_array, W_NDimArray): - raise OperationError(space.w_ValueError, space.wrap( + raise OperationError(space.w_TypeError, space.wrap( '_PyArray_DATA called with non-ndarray')) return rffi.cast(rffi.VOIDP, w_array.implementation.storage) @cpython_api([PyObject, rffi.VOIDP, Py_ssize_t, Py_ssize_t, Py_ssize_t, rffi.VOIDP], - PyObject) + PyObject, error=CANNOT_FAIL) def _PyArray_FromAny(space, w_obj, dtype, min_depth, max_depth, requirements, context): - # ignore all additional arguments for now + """ This is the main function used to obtain an array from any nested + sequence, or object that exposes the array interface, op. The + parameters allow specification of the required dtype, the + minimum (min_depth) and maximum (max_depth) number of dimensions + acceptable, and other requirements for the array. + + The dtype argument needs to be a PyArray_Descr structure indicating + the desired data-type (including required byteorder). The dtype + argument may be NULL, indicating that any data-type (and byteorder) + is acceptable. + Unless FORCECAST is present in flags, this call will generate an error + if the data type cannot be safely obtained from the object. If you + want to use NULL for the dtype and ensure the array is notswapped then + use PyArray_CheckFromAny. + + A value of 0 for either of the depth parameters causes the parameter + to be ignored. + + Any of the following array flags can be added (e.g. using |) to get + the requirements argument. If your code can handle general (e.g. + strided, byte-swapped, or unaligned arrays) then requirements + may be 0. Also, if op is not already an array (or does not expose + the array interface), then a new array will be created (and filled + from op using the sequence protocol). The new array will have + NPY_DEFAULT as its flags member. + + The context argument is passed to the __array__ method of op and is + only used if the array is constructed that way. Almost always this + parameter is NULL. + """ + if dtype: + raise OperationError(space.w_NotImplementedError, space.wrap( + '_PyArray_FromAny called with not-implemented dtype argument')) + if min_depth !=0 or max_depth != 0: + raise OperationError(space.w_NotImplementedError, space.wrap( + '_PyArray_FromAny called with not-implemented min_dpeth or max_depth argument')) + if requirements not in (0, NPY_DEFAULT): + raise OperationError(space.w_NotImplementedError, space.wrap( + '_PyArray_FromAny called with not-implemented requirements argument')) w_array = convert_to_array(space, w_obj) if w_array.is_scalar(): # since PyArray_DATA() fails on scalars, create a 1D array and set empty @@ -151,7 +189,9 @@ @cpython_api([PyObject, Py_ssize_t, Py_ssize_t, Py_ssize_t], PyObject) def _PyArray_FromObject(space, w_obj, typenum, min_depth, max_depth): - # ignore min_depth and max_depth for now + if min_depth !=0 or max_depth != 0: + raise OperationError(space.w_NotImplementedError, space.wrap( + '_PyArray_FromObject called with not-implemented min_dpeth or max_depth argument')) dtype = get_dtype_cache(space).dtypes_by_num[typenum] w_array = convert_to_array(space, w_obj) impl = w_array.implementation diff --git a/pypy/module/cpyext/test/test_ndarrayobject.py b/pypy/module/cpyext/test/test_ndarrayobject.py --- a/pypy/module/cpyext/test/test_ndarrayobject.py +++ b/pypy/module/cpyext/test/test_ndarrayobject.py @@ -62,6 +62,7 @@ def test_NBYTES(self, space, api): a = array(space, [10, 5, 3]) assert api._PyArray_NBYTES(a) == 1200 + self.raises(space, api, TypeError, api._PyArray_NBYTES, space.wrap([10])) def test_TYPE(self, space, api): a = array(space, [10, 5, 3]) @@ -86,6 +87,9 @@ def test_FromAny(self, space, api): a = array(space, [10, 5, 3]) assert api._PyArray_FromAny(a, NULL, 0, 0, 0, NULL) is a + self.raises(space, api, NotImplementedError, api._PyArray_FromAny, + space.wrap(a), space.w_None, space.wrap(0), + space.wrap(3), space.wrap(0), space.w_None) def test_list_from_fixedptr(self, space, api): A = lltype.GcArray(lltype.Float) From noreply at buildbot.pypy.org Mon Sep 9 00:05:13 2013 From: noreply at buildbot.pypy.org (mattip) Date: Mon, 9 Sep 2013 00:05:13 +0200 (CEST) Subject: [pypy-commit] pypy pypy-pyarray: change asserts to exceptions Message-ID: <20130908220513.221D51C12DA@cobra.cs.uni-duesseldorf.de> Author: Matti Picus Branch: pypy-pyarray Changeset: r66852:1331d831dad4 Date: 2013-09-04 15:56 +0300 http://bitbucket.org/pypy/pypy/changeset/1331d831dad4/ Log: change asserts to exceptions diff --git a/pypy/module/cpyext/ndarrayobject.py b/pypy/module/cpyext/ndarrayobject.py --- a/pypy/module/cpyext/ndarrayobject.py +++ b/pypy/module/cpyext/ndarrayobject.py @@ -1,10 +1,11 @@ """ + Numpy C-API for PyPy - S. H. Muller, 2013/07/26 """ from pypy.interpreter.error import OperationError -from rpython.rtyper.lltypesystem import rffi, lltype -from pypy.module.cpyext.api import cpython_api, Py_ssize_t, CANNOT_FAIL +from rpython.rtyper.lltypesystem import rffi +from pypy.module.cpyext.api import cpython_api, Py_ssize_t, CANNOT_FAIL, _NOT_SPECIFIED from pypy.module.cpyext.pyobject import PyObject from pypy.module.micronumpy.interp_numarray import W_NDimArray, convert_to_array, wrap_impl from pypy.module.micronumpy.interp_dtype import get_dtype_cache @@ -56,9 +57,11 @@ w_type = space.gettypeobject(W_NDimArray.typedef) return space.is_w(w_obj_type, w_type) - at cpython_api([PyObject], rffi.INT_real, error=CANNOT_FAIL) + at cpython_api([PyObject], rffi.INT_real, error=-1) def _PyArray_FLAGS(space, w_array): - assert isinstance(w_array, W_NDimArray) + if not isinstance(w_array, W_NDimArray): + raise OperationError(space.w_ValueError, space.wrap( + '_PyArray_FLAGS(ndarray) called with non-ndarray')) flags = NPY_BEHAVED_NS if isinstance(w_array.implementation, ConcreteArray): flags |= NPY_OWNDATA @@ -70,56 +73,72 @@ flags |= NPY_F_CONTIGUOUS return flags - at cpython_api([PyObject], rffi.INT_real, error=CANNOT_FAIL) + at cpython_api([PyObject], rffi.INT_real, error=-1) def _PyArray_NDIM(space, w_array): - assert isinstance(w_array, W_NDimArray) + if not isinstance(w_array, W_NDimArray): + raise OperationError(space.w_ValueError, space.wrap( + '_PyArray_NDIM(ndarray) called with non-ndarray')) return len(w_array.get_shape()) - at cpython_api([PyObject, Py_ssize_t], Py_ssize_t, error=CANNOT_FAIL) + at cpython_api([PyObject, Py_ssize_t], Py_ssize_t, error=-1) def _PyArray_DIM(space, w_array, n): - assert isinstance(w_array, W_NDimArray) + if not isinstance(w_array, W_NDimArray): + raise OperationError(space.w_ValueError, space.wrap( + '_PyArray_DIM called with non-ndarray')) return w_array.get_shape()[n] - at cpython_api([PyObject, Py_ssize_t], Py_ssize_t, error=CANNOT_FAIL) + at cpython_api([PyObject, Py_ssize_t], Py_ssize_t, error=-1) def _PyArray_STRIDE(space, w_array, n): - assert isinstance(w_array, W_NDimArray) + if not isinstance(w_array, W_NDimArray): + raise OperationError(space.w_ValueError, space.wrap( + '_PyArray_STRIDE called with non-ndarray')) return w_array.implementation.get_strides()[n] - at cpython_api([PyObject], Py_ssize_t, error=CANNOT_FAIL) + at cpython_api([PyObject], Py_ssize_t, error=-1) def _PyArray_SIZE(space, w_array): - assert isinstance(w_array, W_NDimArray) + if not isinstance(w_array, W_NDimArray): + raise OperationError(space.w_ValueError, space.wrap( + '_PyArray_SIZE called with non-ndarray')) return w_array.get_size() - at cpython_api([PyObject], rffi.INT_real, error=CANNOT_FAIL) + at cpython_api([PyObject], rffi.INT_real, error=-1) def _PyArray_ITEMSIZE(space, w_array): - assert isinstance(w_array, W_NDimArray) + if not isinstance(w_array, W_NDimArray): + raise OperationError(space.w_ValueError, space.wrap( + '_PyArray_ITEMSIZE called with non-ndarray')) return w_array.get_dtype().get_size() - at cpython_api([PyObject], Py_ssize_t, error=CANNOT_FAIL) + at cpython_api([PyObject], Py_ssize_t, error=-1) def _PyArray_NBYTES(space, w_array): - assert isinstance(w_array, W_NDimArray) + if not isinstance(w_array, W_NDimArray): + raise OperationError(space.w_ValueError, space.wrap( + '_PyArray_NBYTES called with non-ndarray')) return w_array.get_size() * w_array.get_dtype().get_size() - at cpython_api([PyObject], rffi.INT_real, error=CANNOT_FAIL) + at cpython_api([PyObject], rffi.INT_real, error=-1) def _PyArray_TYPE(space, w_array): - assert isinstance(w_array, W_NDimArray) + if not isinstance(w_array, W_NDimArray): + raise OperationError(space.w_ValueError, space.wrap( + '_PyArray_TYPE called with non-ndarray')) return w_array.get_dtype().num - at cpython_api([PyObject], rffi.VOIDP, error=CANNOT_FAIL) + at cpython_api([PyObject], rffi.VOIDP, error=_NOT_SPECIFIED) def _PyArray_DATA(space, w_array): # fails on scalars - see PyArray_FromAny() - assert isinstance(w_array, W_NDimArray) + if not isinstance(w_array, W_NDimArray): + raise OperationError(space.w_ValueError, space.wrap( + '_PyArray_DATA called with non-ndarray')) return rffi.cast(rffi.VOIDP, w_array.implementation.storage) - at cpython_api([PyObject, rffi.VOIDP, Py_ssize_t, Py_ssize_t, Py_ssize_t, rffi.VOIDP], + at cpython_api([PyObject, rffi.VOIDP, Py_ssize_t, Py_ssize_t, Py_ssize_t, rffi.VOIDP], PyObject) def _PyArray_FromAny(space, w_obj, dtype, min_depth, max_depth, requirements, context): # ignore all additional arguments for now w_array = convert_to_array(space, w_obj) if w_array.is_scalar(): - # since PyArray_DATA() fails on scalars, create a 1D array and set empty + # since PyArray_DATA() fails on scalars, create a 1D array and set empty # shape. So the following combination works for *reading* scalars: # PyObject *arr = PyArray_FromAny(obj); # int nd = PyArray_NDIM(arr); @@ -156,15 +175,15 @@ shape, dtype = get_shape_and_dtype(space, nd, dims, typenum) return W_NDimArray.from_shape(space, shape, dtype) -def simple_new_from_data(space, nd, dims, typenum, data, +def simple_new_from_data(space, nd, dims, typenum, data, order='C', owning=False, w_subtype=None): shape, dtype = get_shape_and_dtype(space, nd, dims, typenum) storage = rffi.cast(RAW_STORAGE_PTR, data) if nd == 0: w_val = dtype.itemtype.box_raw_data(storage) return W_NDimArray(Scalar(dtype, w_val)) - else: - return W_NDimArray.from_shape_and_storage(space, shape, storage, dtype, + else: + return W_NDimArray.from_shape_and_storage(space, shape, storage, dtype, order=order, owning=owning, w_subtype=w_subtype) @@ -188,7 +207,7 @@ rffi.VOIDP, Py_ssize_t, Py_ssize_t, PyObject], PyObject) def _PyArray_New(space, subtype, nd, dims, typenum, strides, data, itemsize, flags, obj): if strides: - raise OperationError(space.w_NotImplementedError, + raise OperationError(space.w_NotImplementedError, space.wrap("strides must be NULL")) order = 'C' if flags & NPY_C_CONTIGUOUS else 'F' @@ -196,11 +215,9 @@ w_subtype = None if data: - return simple_new_from_data(space, nd, dims, typenum, data, + return simple_new_from_data(space, nd, dims, typenum, data, order=order, owning=owning, w_subtype=w_subtype) else: return simple_new(space, nd, dims, typenum, order=order, owning=owning, w_subtype=w_subtype) - - diff --git a/pypy/module/cpyext/test/test_ndarrayobject.py b/pypy/module/cpyext/test/test_ndarrayobject.py --- a/pypy/module/cpyext/test/test_ndarrayobject.py +++ b/pypy/module/cpyext/test/test_ndarrayobject.py @@ -42,7 +42,7 @@ assert api._PyArray_FLAGS(f) & 0x0002 assert not api._PyArray_FLAGS(c) & 0x0002 assert not api._PyArray_FLAGS(f) & 0x0001 - + def test_NDIM(self, space, api): a = array(space, [10, 5, 3]) assert api._PyArray_NDIM(a) == 3 @@ -58,7 +58,7 @@ def test_ITEMSIZE(self, space, api): a = array(space, [10, 5, 3]) assert api._PyArray_ITEMSIZE(a) == 8 - + def test_NBYTES(self, space, api): a = array(space, [10, 5, 3]) assert api._PyArray_NBYTES(a) == 1200 @@ -79,7 +79,7 @@ a = api._PyArray_FromAny(a0, NULL, 0, 0, 0, NULL) assert api._PyArray_NDIM(a) == 0 - + ptr = rffi.cast(rffi.DOUBLEP, api._PyArray_DATA(a)) assert ptr[0] == 10. @@ -112,9 +112,9 @@ def test_SimpleNew_scalar(self, space, api): ptr_s = lltype.nullptr(rffi.LONGP.TO) a = api._PyArray_SimpleNew(0, ptr_s, 12) - + dtype = get_dtype_cache(space).w_float64dtype - + a.set_scalar_value(dtype.itemtype.box(10.)) assert a.get_scalar_value().value == 10. @@ -127,7 +127,7 @@ x[0] = float(10.) ptr_s = lltype.nullptr(rffi.LONGP.TO) - + res = api._PyArray_SimpleNewFromData(0, ptr_s, num, ptr_a) assert res.is_scalar() assert res.get_scalar_value().value == 10. @@ -141,9 +141,9 @@ ptr_s[0] = 10 ptr_s[1] = 5 ptr_s[2] = 3 - + a = api._PyArray_SimpleNew(nd, ptr_s, 12) - + #assert list(api._PyArray_DIMS(a))[:3] == shape ptr_a = api._PyArray_DATA(a) @@ -185,13 +185,13 @@ def test_SimpleNewFromData_complex(self, space, api): a = array(space, [2]) ptr_a = api._PyArray_DATA(a) - + x = rffi.cast(rffi.DOUBLEP, ptr_a) x[0] = 3. x[1] = 4. - + ptr_s = lltype.nullptr(rffi.LONGP.TO) - + res = api._PyArray_SimpleNewFromData(0, ptr_s, 15, ptr_a) assert res.get_scalar_value().real == 3. assert res.get_scalar_value().imag == 4. From noreply at buildbot.pypy.org Mon Sep 9 00:05:16 2013 From: noreply at buildbot.pypy.org (mattip) Date: Mon, 9 Sep 2013 00:05:16 +0200 (CEST) Subject: [pypy-commit] pypy pypy-pyarray: add failing ztranslation test Message-ID: <20130908220516.C84B61C1356@cobra.cs.uni-duesseldorf.de> Author: Matti Picus Branch: pypy-pyarray Changeset: r66855:fce071483285 Date: 2013-09-08 23:47 +0200 http://bitbucket.org/pypy/pypy/changeset/fce071483285/ Log: add failing ztranslation test diff --git a/pypy/module/cpyext/test/test_ztranslation.py b/pypy/module/cpyext/test/test_ztranslation.py new file mode 100644 --- /dev/null +++ b/pypy/module/cpyext/test/test_ztranslation.py @@ -0,0 +1,4 @@ +from pypy.objspace.fake.checkmodule import checkmodule + +def test_cpyext_translates(): + checkmodule('cpyext', '_ffi') From noreply at buildbot.pypy.org Mon Sep 9 00:05:17 2013 From: noreply at buildbot.pypy.org (mattip) Date: Mon, 9 Sep 2013 00:05:17 +0200 (CEST) Subject: [pypy-commit] pypy pypy-pyarray: remove finished tasks Message-ID: <20130908220517.EE7A91C12DA@cobra.cs.uni-duesseldorf.de> Author: Matti Picus Branch: pypy-pyarray Changeset: r66856:77f0aff71764 Date: 2013-09-09 00:03 +0200 http://bitbucket.org/pypy/pypy/changeset/77f0aff71764/ Log: remove finished tasks diff --git a/TODO.txt b/TODO.txt --- a/TODO.txt +++ b/TODO.txt @@ -4,12 +4,6 @@ - why do we need to implement array.nonzero on this branch and it was not done e.g. on default? -- def _PyArray_FromAny(space, w_obj, dtype, min_depth, max_depth, requirements, context): - # ignore all additional arguments for now - - this sounds bad. We think it'd be better to emit a warning/exception in case - we pass arguments with a non-default value. The same for _PyArray_FromObject - - def get_shape_and_dtype(space, nd, dims, typenum): shape = [] for i in range(nd): @@ -23,9 +17,6 @@ fine to have a half-working implementation, but it should raise an exception if it's passed - - - TODO list by mattip =================== @@ -35,7 +26,7 @@ - test all *.h files under pypy/module/cpyext/include/numpy - make sure all cpyext changes are tested: PyBoolObject (new) - PyComplexFromCComplex() (changed, problematic) + PyComplexFromCComplex() (changed, problematic for c++?) PyFunctionType (new) PyMethodType (new) PyRangeType (new) @@ -49,5 +40,3 @@ PyNumberCoerce() (new) - test require_index in create_iter, get_index in iter - test use of __array__() and friends -- test complex data types in dtypes_by_num -- From noreply at buildbot.pypy.org Mon Sep 9 09:46:52 2013 From: noreply at buildbot.pypy.org (arigo) Date: Mon, 9 Sep 2013 09:46:52 +0200 (CEST) Subject: [pypy-commit] stmgc default: Skip this assert, after discussion with Remi. Message-ID: <20130909074652.112F21C0165@cobra.cs.uni-duesseldorf.de> Author: Armin Rigo Branch: Changeset: r525:698910c9edc3 Date: 2013-09-09 09:46 +0200 http://bitbucket.org/pypy/stmgc/changeset/698910c9edc3/ Log: Skip this assert, after discussion with Remi. diff --git a/c4/gcpage.c b/c4/gcpage.c --- a/c4/gcpage.c +++ b/c4/gcpage.c @@ -503,7 +503,9 @@ G2L_LOOP_FORWARD(registered_stubs, item) { gcptr R = item->addr; assert(R->h_tid & GCFLAG_SMALLSTUB); - assert(!(R->h_tid & (GCFLAG_VISITED | GCFLAG_MARKED))); + /* The following assert can fail if we have a stub pointing to + a stub and both are registered_stubs. This case is benign. */ + //assert(!(R->h_tid & (GCFLAG_VISITED | GCFLAG_MARKED))); R->h_tid |= (GCFLAG_MARKED | GCFLAG_VISITED); From noreply at buildbot.pypy.org Mon Sep 9 09:47:34 2013 From: noreply at buildbot.pypy.org (arigo) Date: Mon, 9 Sep 2013 09:47:34 +0200 (CEST) Subject: [pypy-commit] pypy stmgc-c4: import stmgc/698910c9edc3 Message-ID: <20130909074734.4591F1C016D@cobra.cs.uni-duesseldorf.de> Author: Armin Rigo Branch: stmgc-c4 Changeset: r66857:533cd1f88e46 Date: 2013-09-09 09:46 +0200 http://bitbucket.org/pypy/pypy/changeset/533cd1f88e46/ Log: import stmgc/698910c9edc3 diff --git a/rpython/translator/stm/src_stm/gcpage.c b/rpython/translator/stm/src_stm/gcpage.c --- a/rpython/translator/stm/src_stm/gcpage.c +++ b/rpython/translator/stm/src_stm/gcpage.c @@ -504,7 +504,9 @@ G2L_LOOP_FORWARD(registered_stubs, item) { gcptr R = item->addr; assert(R->h_tid & GCFLAG_SMALLSTUB); - assert(!(R->h_tid & (GCFLAG_VISITED | GCFLAG_MARKED))); + /* The following assert can fail if we have a stub pointing to + a stub and both are registered_stubs. This case is benign. */ + //assert(!(R->h_tid & (GCFLAG_VISITED | GCFLAG_MARKED))); R->h_tid |= (GCFLAG_MARKED | GCFLAG_VISITED); diff --git a/rpython/translator/stm/src_stm/revision b/rpython/translator/stm/src_stm/revision --- a/rpython/translator/stm/src_stm/revision +++ b/rpython/translator/stm/src_stm/revision @@ -1,1 +1,1 @@ -782ebd6afc03 +698910c9edc3 From noreply at buildbot.pypy.org Mon Sep 9 11:18:07 2013 From: noreply at buildbot.pypy.org (arigo) Date: Mon, 9 Sep 2013 11:18:07 +0200 (CEST) Subject: [pypy-commit] pypy default: This argument is always -1. Kill the (broken) support for different Message-ID: <20130909091807.97ED41C1128@cobra.cs.uni-duesseldorf.de> Author: Armin Rigo Branch: Changeset: r66858:e86991796de2 Date: 2013-09-09 11:17 +0200 http://bitbucket.org/pypy/pypy/changeset/e86991796de2/ Log: This argument is always -1. Kill the (broken) support for different values. 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 @@ -621,7 +621,7 @@ 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): + def _check_frame_depth(self, mc, gcmap): """ check if the frame is of enough depth to follow this bridge. Otherwise reallocate the frame in a helper. There are other potential solutions @@ -629,17 +629,11 @@ """ descrs = self.cpu.gc_ll_descr.getframedescrs(self.cpu) ofs = self.cpu.unpack_fielddescr(descrs.arraydescr.lendescr) - if expected_size == -1: - mc.CMP_bi(ofs, 0xffffff) - else: - mc.CMP_bi(ofs, expected_size) + mc.CMP_bi(ofs, 0xffffff) # force writing 32 bit stack_check_cmp_ofs = mc.get_relative_pos() - 4 mc.J_il8(rx86.Conditions['GE'], 0) jg_location = mc.get_relative_pos() - if expected_size == -1: - mc.MOV_si(WORD, 0xffffff) - else: - mc.MOV_si(WORD, expected_size) + mc.MOV_si(WORD, 0xffffff) # force writing 32 bit ofs2 = mc.get_relative_pos() - 4 self.push_gcmap(mc, gcmap, mov=True) mc.CALL(imm(self._frame_realloc_slowpath)) From noreply at buildbot.pypy.org Mon Sep 9 16:02:47 2013 From: noreply at buildbot.pypy.org (arigo) Date: Mon, 9 Sep 2013 16:02:47 +0200 (CEST) Subject: [pypy-commit] pypy stmgc-c4: Crash more cleanly when trying to translate on 32-bit (duh) Message-ID: <20130909140247.C0C2B1C12DA@cobra.cs.uni-duesseldorf.de> Author: Armin Rigo Branch: stmgc-c4 Changeset: r66860:07dc1406b5e1 Date: 2013-09-09 16:02 +0200 http://bitbucket.org/pypy/pypy/changeset/07dc1406b5e1/ Log: Crash more cleanly when trying to translate on 32-bit (duh) 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 @@ -2406,7 +2406,8 @@ # read_barrier: # (obj->h_revision != stm_private_rev_num) # && (FXCACHE_AT(obj) != obj))) - assert not IS_X86_32 # XXX: todo + if IS_X86_32: # XXX: todo + todo() jz_location = 0 jz_location2 = 0 jnz_location = 0 @@ -2889,5 +2890,8 @@ cond_call_register_arguments = [edi, esi, edx, ecx] +def todo(): + CRASH # not done yet + class BridgeAlreadyCompiled(Exception): pass From noreply at buildbot.pypy.org Mon Sep 9 16:02:46 2013 From: noreply at buildbot.pypy.org (arigo) Date: Mon, 9 Sep 2013 16:02:46 +0200 (CEST) Subject: [pypy-commit] pypy stmgc-c4: Make the raw JITFRAMEINFO STM-free, by using only one field in case Message-ID: <20130909140246.A3D611C1128@cobra.cs.uni-duesseldorf.de> Author: Armin Rigo Branch: stmgc-c4 Changeset: r66859:663ecda0e4d8 Date: 2013-09-09 14:30 +0200 http://bitbucket.org/pypy/pypy/changeset/663ecda0e4d8/ Log: Make the raw JITFRAMEINFO STM-free, by using only one field in case of STM and by updating its value carefully with bool_cas(). 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 @@ -3,6 +3,7 @@ from rpython.rlib.objectmodel import specialize from rpython.rlib.debug import ll_assert from rpython.rlib.objectmodel import enforceargs +from rpython.rlib.rgc import stm_is_enabled SIZEOFSIGNED = rffi.sizeof(lltype.Signed) IS_32BIT = (SIZEOFSIGNED == 4) @@ -16,6 +17,22 @@ @enforceargs(None, int, int) def jitframeinfo_update_depth(jfi, base_ofs, new_depth): + # + if stm_is_enabled(): + from rpython.rlib.atomic_ops import bool_cas + # careful here, 'jfi' has 'stm_dont_track_raw_accesses' + while True: + old_depth = jfi.jfi_frame_depth + if new_depth <= old_depth: + break # only ever increase the depth + if bool_cas(rffi.cast(llmemory.Address, jfi), + rffi.cast(llmemory.Address, old_depth), + rffi.cast(llmemory.Address, new_depth)): + break + # note that we don't set jfi_frame_size at all if STM, + # to avoid concurrency issues + return + # if new_depth > jfi.jfi_frame_depth: jfi.jfi_frame_depth = new_depth jfi.jfi_frame_size = base_ofs + new_depth * SIZEOFSIGNED @@ -31,11 +48,12 @@ # the depth of the frame ('jfi_frame_depth', lltype.Signed), # the total size of the frame, in bytes - ('jfi_frame_size', lltype.Signed), + ('jfi_frame_size', lltype.Signed), # <- not set if STM adtmeths = { 'update_frame_depth': jitframeinfo_update_depth, 'clear': jitframeinfo_clear, }, + hints = {'stm_dont_track_raw_accesses': True}, ) NULLFRAMEINFO = lltype.nullptr(JITFRAMEINFO) 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 @@ -157,9 +157,10 @@ else: raise NotImplementedError(op.getopname()) - def gen_malloc_frame(self, frame_info, frame, size_box): + def gen_malloc_frame(self, frame_info, frame): + size_box = history.BoxInt() descrs = self.gc_ll_descr.getframedescrs(self.cpu) - if self.gc_ll_descr.kind == 'boehm': + if self.gc_ll_descr.kind == 'boehm' or self.gc_ll_descr.stm: op0 = ResOperation(rop.GETFIELD_GC, [history.ConstInt(frame_info)], size_box, descr=descrs.jfi_frame_depth) @@ -169,6 +170,7 @@ self.handle_new_array(descrs.arraydescr, op1) else: # we read size in bytes here, not the length + # (this path is only used in non-STM mode) op0 = ResOperation(rop.GETFIELD_GC, [history.ConstInt(frame_info)], size_box, descr=descrs.jfi_frame_size) @@ -189,9 +191,8 @@ assert isinstance(loop_token, history.JitCellToken) jfi = loop_token.compiled_loop_token.frame_info llfi = heaptracker.adr2int(llmemory.cast_ptr_to_adr(jfi)) - size_box = history.BoxInt() frame = history.BoxPtr() - self.gen_malloc_frame(llfi, frame, size_box) + self.gen_malloc_frame(llfi, frame) op2 = ResOperation(rop.SETFIELD_GC, [frame, history.ConstInt(llfi)], None, descr=descrs.jf_frame_info) self.newops.append(op2) diff --git a/rpython/jit/backend/llsupport/stmrewrite.py b/rpython/jit/backend/llsupport/stmrewrite.py --- a/rpython/jit/backend/llsupport/stmrewrite.py +++ b/rpython/jit/backend/llsupport/stmrewrite.py @@ -152,13 +152,13 @@ if c == 'R': self.known_category[v] = 'P' - def gen_malloc_nursery_varsize_frame(self, sizebox, v_result, tid): - """ For now don't generate CALL_MALLOC_NURSERY_VARSIZE_FRAME - """ - addr = self.gc_ll_descr.get_malloc_fn_addr('malloc_big_fixedsize') - args = [ConstInt(addr), sizebox, ConstInt(tid)] - descr = self.gc_ll_descr.malloc_big_fixedsize_descr - self._gen_call_malloc_gc(args, v_result, descr) +## def gen_malloc_nursery_varsize_frame(self, sizebox, v_result, tid): +## """ For now don't generate CALL_MALLOC_NURSERY_VARSIZE_FRAME +## """ +## addr = self.gc_ll_descr.get_malloc_fn_addr('malloc_big_fixedsize') +## args = [ConstInt(addr), sizebox, ConstInt(tid)] +## descr = self.gc_ll_descr.malloc_big_fixedsize_descr +## self._gen_call_malloc_gc(args, v_result, descr) def gen_write_barrier(self, v): raise NotImplementedError From noreply at buildbot.pypy.org Mon Sep 9 16:35:44 2013 From: noreply at buildbot.pypy.org (arigo) Date: Mon, 9 Sep 2013 16:35:44 +0200 (CEST) Subject: [pypy-commit] pypy stmgc-c4: Debugging: always fprintf the inevitable reasons Message-ID: <20130909143544.BB8CD1C12DA@cobra.cs.uni-duesseldorf.de> Author: Armin Rigo Branch: stmgc-c4 Changeset: r66861:781b5647ee58 Date: 2013-09-09 16:24 +0200 http://bitbucket.org/pypy/pypy/changeset/781b5647ee58/ Log: Debugging: always fprintf the inevitable reasons diff --git a/rpython/jit/tl/targettlr.py b/rpython/jit/tl/targettlr.py --- a/rpython/jit/tl/targettlr.py +++ b/rpython/jit/tl/targettlr.py @@ -12,12 +12,20 @@ # viewcode.py to know the executable whose symbols it should display) highleveljitinfo.sys_executable = args[0] if len(args) < 3: - print "Usage: %s filename x" % (args[0],) + print "Usage: %s filename x (repetition)" % (args[0],) return 2 filename = args[1] x = int(args[2]) + if len(args) == 3: + repetition = 1 + else: + repetition = int(args[3]) bytecode = load_bytecode(filename) - res = interpret(bytecode, x) + while True: + res = interpret(bytecode, x) + repetition -= 1 + if repetition <= 0: + break print res return 0 diff --git a/rpython/translator/stm/src_stm/et.c b/rpython/translator/stm/src_stm/et.c --- a/rpython/translator/stm/src_stm/et.c +++ b/rpython/translator/stm/src_stm/et.c @@ -1531,8 +1531,8 @@ (XXX statically we should know when we're outside a transaction) */ - dprintf(("[%lx] inevitable: %s\n", - (long)d->public_descriptor_index, why)); + fprintf(stderr, "[%lx] inevitable: %s\n", + (long)d->public_descriptor_index, why); cur_time = acquire_inev_mutex_and_mark_global_cur_time(d); if (d->start_time != cur_time) From noreply at buildbot.pypy.org Mon Sep 9 16:35:46 2013 From: noreply at buildbot.pypy.org (arigo) Date: Mon, 9 Sep 2013 16:35:46 +0200 (CEST) Subject: [pypy-commit] pypy stmgc-c4: Handle gc_writebarrier in stm/writebarrier.py Message-ID: <20130909143546.14C641C12EC@cobra.cs.uni-duesseldorf.de> Author: Armin Rigo Branch: stmgc-c4 Changeset: r66862:97ea6facc2a3 Date: 2013-09-09 16:31 +0200 http://bitbucket.org/pypy/pypy/changeset/97ea6facc2a3/ Log: Handle gc_writebarrier in stm/writebarrier.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 @@ -745,6 +745,7 @@ resultvar=op.result) def gct_gc_writebarrier(self, hop): + assert not self.translator.config.stm # removed by stm/writebarrier.py if self.write_barrier_ptr is None: return op = hop.spaceop @@ -897,6 +898,7 @@ gen_zero_gc_pointers(TYPE, v_ob, hop.llops) def gct_gc_writebarrier_before_copy(self, hop): + assert not self.translator.config.stm # should not be produced if stm op = hop.spaceop if not hasattr(self, 'wb_before_copy_ptr'): # no write barrier needed in that case diff --git a/rpython/translator/stm/test/test_writebarrier.py b/rpython/translator/stm/test/test_writebarrier.py --- a/rpython/translator/stm/test/test_writebarrier.py +++ b/rpython/translator/stm/test/test_writebarrier.py @@ -521,6 +521,15 @@ self.interpret(f1, []) assert self.barriers == ['a2i'] + def test_llop_gc_writebarrier(self): + FOO = lltype.GcStruct('FOO') + x = lltype.malloc(FOO, immortal=True) + def f1(): + llop.gc_writebarrier(lltype.Void, x) + + self.interpret(f1, []) + assert self.barriers == ['I2W'] + external_release_gil = rffi.llexternal('external_release_gil', [], lltype.Void, _callable=lambda: None, diff --git a/rpython/translator/stm/test/transform_support.py b/rpython/translator/stm/test/transform_support.py --- a/rpython/translator/stm/test/transform_support.py +++ b/rpython/translator/stm/test/transform_support.py @@ -165,3 +165,9 @@ def op_stm_begin_inevitable_transaction(self): self.transaction_break() + + def op_gc_writebarrier(self, p): + raise Exception("should have been removed") + + def op_gc_writebarrier_before_copy(self, p): + raise Exception("should not be produced at all") diff --git a/rpython/translator/stm/writebarrier.py b/rpython/translator/stm/writebarrier.py --- a/rpython/translator/stm/writebarrier.py +++ b/rpython/translator/stm/writebarrier.py @@ -113,6 +113,9 @@ elif op.opname == 'weakref_deref': # 'weakref_deref' needs an immutable read barrier wants_a_barrier[op] = 'I' + + elif op.opname == 'gc_writebarrier': + wants_a_barrier[op] = 'W' # self.wants_a_barrier = wants_a_barrier self.expand_comparison = expand_comparison @@ -196,6 +199,8 @@ newoperations.append(newop) ren.newvar = w ren.category = to + if op.opname == 'gc_writebarrier': + continue # remove after inserting 'stm_barrier' # newop = SpaceOperation(op.opname, [renamings_get(v) for v in op.args], From noreply at buildbot.pypy.org Mon Sep 9 16:43:05 2013 From: noreply at buildbot.pypy.org (arigo) Date: Mon, 9 Sep 2013 16:43:05 +0200 (CEST) Subject: [pypy-commit] pypy stmgc-c4: Fix Message-ID: <20130909144305.7771A1C0165@cobra.cs.uni-duesseldorf.de> Author: Armin Rigo Branch: stmgc-c4 Changeset: r66863:4a08783e2fa4 Date: 2013-09-09 16:38 +0200 http://bitbucket.org/pypy/pypy/changeset/4a08783e2fa4/ Log: Fix 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 @@ -745,7 +745,8 @@ resultvar=op.result) def gct_gc_writebarrier(self, hop): - assert not self.translator.config.stm # removed by stm/writebarrier.py + # this operation is removed by stm/writebarrier.py + assert not self.translator.config.translation.stm if self.write_barrier_ptr is None: return op = hop.spaceop @@ -898,7 +899,8 @@ gen_zero_gc_pointers(TYPE, v_ob, hop.llops) def gct_gc_writebarrier_before_copy(self, hop): - assert not self.translator.config.stm # should not be produced if stm + # this operation should not be produced if stm + assert not self.translator.config.translation.stm op = hop.spaceop if not hasattr(self, 'wb_before_copy_ptr'): # no write barrier needed in that case From noreply at buildbot.pypy.org Mon Sep 9 17:50:07 2013 From: noreply at buildbot.pypy.org (arigo) Date: Mon, 9 Sep 2013 17:50:07 +0200 (CEST) Subject: [pypy-commit] pypy default: Simplify the code and always call {read, write}_{int, ref, float}_at_mem(). Message-ID: <20130909155007.D6BD81C02A7@cobra.cs.uni-duesseldorf.de> Author: Armin Rigo Branch: Changeset: r66864:e35d638cb427 Date: 2013-09-09 17:30 +0200 http://bitbucket.org/pypy/pypy/changeset/e35d638cb427/ Log: Simplify the code and always call {read,write}_{int,ref,float}_at_mem(). 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 @@ -386,7 +386,7 @@ raise NotImplementedError("size = %d" % size) @specialize.argtype(1) - def write_int_at_mem(self, gcref, ofs, size, sign, newvalue): + def write_int_at_mem(self, gcref, ofs, size, newvalue): # --- start of GC unsafe code (no GC operation!) --- items = rffi.ptradd(rffi.cast(rffi.CCHARP, gcref), ofs) for TYPE, _, itemsize in unroll_basic_sizes: @@ -439,7 +439,7 @@ """ descr = self.gc_ll_descr.getframedescrs(self).arraydescr ofs = self.unpack_arraydescr(descr) - self.write_int_at_mem(newframe, ofs + index, WORD, 1, value) + self.write_int_at_mem(newframe, ofs + index, WORD, value) def set_ref_value(self, newframe, index, value): descr = self.gc_ll_descr.getframedescrs(self).arraydescr @@ -467,7 +467,7 @@ def bh_arraylen_gc(self, array, arraydescr): assert isinstance(arraydescr, ArrayDescr) ofs = arraydescr.lendescr.offset - return rffi.cast(rffi.CArrayPtr(lltype.Signed), array)[ofs/WORD] + return self.read_int_at_mem(array, ofs, WORD, 1) @specialize.argtype(1) def bh_getarrayitem_gc_i(self, gcref, itemindex, arraydescr): @@ -488,8 +488,7 @@ @specialize.argtype(1) def bh_setarrayitem_gc_i(self, gcref, itemindex, newvalue, arraydescr): ofs, size, sign = self.unpack_arraydescr_size(arraydescr) - self.write_int_at_mem(gcref, ofs + itemindex * size, size, sign, - newvalue) + self.write_int_at_mem(gcref, ofs + itemindex * size, size, newvalue) def bh_setarrayitem_gc_r(self, gcref, itemindex, newvalue, arraydescr): ofs = self.unpack_arraydescr(arraydescr) @@ -509,97 +508,43 @@ def bh_getinteriorfield_gc_i(self, gcref, itemindex, descr): assert isinstance(descr, InteriorFieldDescr) - arraydescr = descr.arraydescr - ofs, size, _ = self.unpack_arraydescr_size(arraydescr) - ofs += descr.fielddescr.offset - fieldsize = descr.fielddescr.field_size - sign = descr.fielddescr.is_field_signed() - fullofs = itemindex * size + ofs - # --- start of GC unsafe code (no GC operation!) --- - items = rffi.ptradd(rffi.cast(rffi.CCHARP, gcref), fullofs) - for STYPE, UTYPE, itemsize in unroll_basic_sizes: - if fieldsize == itemsize: - if sign: - item = rffi.cast(rffi.CArrayPtr(STYPE), items) - val = item[0] - val = rffi.cast(lltype.Signed, val) - else: - item = rffi.cast(rffi.CArrayPtr(UTYPE), items) - val = item[0] - val = rffi.cast(lltype.Signed, val) - # --- end of GC unsafe code --- - return val - else: - raise NotImplementedError("size = %d" % fieldsize) + ofs, size, _ = self.unpack_arraydescr_size(descr.arraydescr) + fldofs, fldsize, sign = self.unpack_fielddescr_size(descr.fielddescr) + ofs += itemindex * size + fldofs + return self.read_int_at_mem(gcref, ofs, fldsize, sign) def bh_getinteriorfield_gc_r(self, gcref, itemindex, descr): assert isinstance(descr, InteriorFieldDescr) - arraydescr = descr.arraydescr - ofs, size, _ = self.unpack_arraydescr_size(arraydescr) + ofs, size, _ = self.unpack_arraydescr_size(descr.arraydescr) ofs += descr.fielddescr.offset - # --- start of GC unsafe code (no GC operation!) --- - items = rffi.ptradd(rffi.cast(rffi.CCHARP, gcref), ofs + - size * itemindex) - items = rffi.cast(rffi.CArrayPtr(lltype.Signed), items) - pval = self._cast_int_to_gcref(items[0]) - # --- end of GC unsafe code --- - return pval + fullofs = itemindex * size + ofs + return self.read_ref_at_mem(gcref, fullofs) def bh_getinteriorfield_gc_f(self, gcref, itemindex, descr): assert isinstance(descr, InteriorFieldDescr) - arraydescr = descr.arraydescr - ofs, size, _ = self.unpack_arraydescr_size(arraydescr) + ofs, size, _ = self.unpack_arraydescr_size(descr.arraydescr) ofs += descr.fielddescr.offset - # --- start of GC unsafe code (no GC operation!) --- - items = rffi.ptradd(rffi.cast(rffi.CCHARP, gcref), ofs + - size * itemindex) - items = rffi.cast(rffi.CArrayPtr(longlong.FLOATSTORAGE), items) - fval = items[0] - # --- end of GC unsafe code --- - return fval + fullofs = itemindex * size + ofs + return self.read_float_at_mem(gcref, fullofs) - def bh_setinteriorfield_gc_i(self, gcref, itemindex, value, descr): + def bh_setinteriorfield_gc_i(self, gcref, itemindex, newvalue, descr): assert isinstance(descr, InteriorFieldDescr) - arraydescr = descr.arraydescr - ofs, size, _ = self.unpack_arraydescr_size(arraydescr) - ofs += descr.fielddescr.offset - fieldsize = descr.fielddescr.field_size - ofs = itemindex * size + ofs - # --- start of GC unsafe code (no GC operation!) --- - items = rffi.ptradd(rffi.cast(rffi.CCHARP, gcref), ofs) - for TYPE, _, itemsize in unroll_basic_sizes: - if fieldsize == itemsize: - items = rffi.cast(rffi.CArrayPtr(TYPE), items) - items[0] = rffi.cast(TYPE, value) - # --- end of GC unsafe code --- - return - else: - raise NotImplementedError("size = %d" % fieldsize) + ofs, size, _ = self.unpack_arraydescr_size(descr.arraydescr) + fldofs, fldsize, _ = self.unpack_fielddescr_size(descr.fielddescr) + ofs += itemindex * size + fldofs + self.write_int_at_mem(gcref, ofs, fldsize, newvalue) def bh_setinteriorfield_gc_r(self, gcref, itemindex, newvalue, descr): assert isinstance(descr, InteriorFieldDescr) - arraydescr = descr.arraydescr - ofs, size, _ = self.unpack_arraydescr_size(arraydescr) - ofs += descr.fielddescr.offset - self.gc_ll_descr.do_write_barrier(gcref, newvalue) - # --- start of GC unsafe code (no GC operation!) --- - items = rffi.ptradd(rffi.cast(rffi.CCHARP, gcref), - ofs + size * itemindex) - items = rffi.cast(rffi.CArrayPtr(lltype.Signed), items) - items[0] = self.cast_gcref_to_int(newvalue) - # --- end of GC unsafe code --- + ofs, size, _ = self.unpack_arraydescr_size(descr.arraydescr) + ofs += itemindex * size + descr.fielddescr.offset + self.write_ref_at_mem(gcref, ofs, newvalue) def bh_setinteriorfield_gc_f(self, gcref, itemindex, newvalue, descr): assert isinstance(descr, InteriorFieldDescr) - arraydescr = descr.arraydescr - ofs, size, _ = self.unpack_arraydescr_size(arraydescr) - ofs += descr.fielddescr.offset - # --- start of GC unsafe code (no GC operation!) --- - items = rffi.ptradd(rffi.cast(rffi.CCHARP, gcref), - ofs + size * itemindex) - items = rffi.cast(rffi.CArrayPtr(longlong.FLOATSTORAGE), items) - items[0] = newvalue - # --- end of GC unsafe code --- + ofs, size, _ = self.unpack_arraydescr_size(descr.arraydescr) + ofs += itemindex * size + descr.fielddescr.offset + self.write_float_at_mem(gcref, ofs, newvalue) def bh_strlen(self, string): s = lltype.cast_opaque_ptr(lltype.Ptr(rstr.STR), string) @@ -618,106 +563,46 @@ return ord(u.chars[index]) @specialize.argtype(1) - def _base_do_getfield_i(self, struct, fielddescr): + def bh_getfield_gc_i(self, struct, fielddescr): ofs, size, sign = self.unpack_fielddescr_size(fielddescr) - # --- start of GC unsafe code (no GC operation!) --- - fieldptr = rffi.ptradd(rffi.cast(rffi.CCHARP, struct), ofs) - for STYPE, UTYPE, itemsize in unroll_basic_sizes: - if size == itemsize: - # Note that in the common case where size==sizeof(Signed), - # both cases of what follows are doing the same thing. - # But gcc is clever enough to figure this out :-) - if sign: - val = rffi.cast(rffi.CArrayPtr(STYPE), fieldptr)[0] - val = rffi.cast(lltype.Signed, val) - else: - val = rffi.cast(rffi.CArrayPtr(UTYPE), fieldptr)[0] - val = rffi.cast(lltype.Signed, val) - # --- end of GC unsafe code --- - return val - else: - raise NotImplementedError("size = %d" % size) + return self.read_int_at_mem(struct, ofs, size, sign) + + def bh_getfield_gc_r(self, struct, fielddescr): + ofs = self.unpack_fielddescr(fielddescr) + return self.read_ref_at_mem(struct, ofs) @specialize.argtype(1) - def _base_do_getfield_r(self, struct, fielddescr): + def bh_getfield_gc_f(self, struct, fielddescr): ofs = self.unpack_fielddescr(fielddescr) - # --- start of GC unsafe code (no GC operation!) --- - fieldptr = rffi.ptradd(rffi.cast(rffi.CCHARP, struct), ofs) - pval = rffi.cast(rffi.CArrayPtr(lltype.Signed), fieldptr)[0] - pval = self._cast_int_to_gcref(pval) - # --- end of GC unsafe code --- - return pval + return self.read_float_at_mem(struct, ofs) + + bh_getfield_raw_i = bh_getfield_gc_i + bh_getfield_raw_f = bh_getfield_gc_f @specialize.argtype(1) - def _base_do_getfield_f(self, struct, fielddescr): + def bh_setfield_gc_i(self, struct, newvalue, fielddescr): + ofs, size, _ = self.unpack_fielddescr_size(fielddescr) + self.write_int_at_mem(struct, ofs, size, newvalue) + + def bh_setfield_gc_r(self, struct, newvalue, fielddescr): ofs = self.unpack_fielddescr(fielddescr) - # --- start of GC unsafe code (no GC operation!) --- - fieldptr = rffi.ptradd(rffi.cast(rffi.CCHARP, struct), ofs) - fval = rffi.cast(rffi.CArrayPtr(longlong.FLOATSTORAGE), fieldptr)[0] - # --- end of GC unsafe code --- - return fval - - bh_getfield_gc_i = _base_do_getfield_i - bh_getfield_gc_r = _base_do_getfield_r - bh_getfield_gc_f = _base_do_getfield_f - bh_getfield_raw_i = _base_do_getfield_i - bh_getfield_raw_r = _base_do_getfield_r - bh_getfield_raw_f = _base_do_getfield_f + self.write_ref_at_mem(struct, ofs, newvalue) @specialize.argtype(1) - def _base_do_setfield_i(self, struct, newvalue, fielddescr): - ofs, size, sign = self.unpack_fielddescr_size(fielddescr) - # --- start of GC unsafe code (no GC operation!) --- - fieldptr = rffi.ptradd(rffi.cast(rffi.CCHARP, struct), ofs) - for TYPE, _, itemsize in unroll_basic_sizes: - if size == itemsize: - fieldptr = rffi.cast(rffi.CArrayPtr(TYPE), fieldptr) - fieldptr[0] = rffi.cast(TYPE, newvalue) - # --- end of GC unsafe code --- - return - else: - raise NotImplementedError("size = %d" % size) + def bh_setfield_gc_f(self, struct, newvalue, fielddescr): + ofs = self.unpack_fielddescr(fielddescr) + self.write_float_at_mem(struct, ofs, newvalue) - @specialize.argtype(1) - def _base_do_setfield_r(self, struct, newvalue, fielddescr): - ofs = self.unpack_fielddescr(fielddescr) - assert lltype.typeOf(struct) is not lltype.Signed, ( - "can't handle write barriers for setfield_raw") - self.gc_ll_descr.do_write_barrier(struct, newvalue) - # --- start of GC unsafe code (no GC operation!) --- - fieldptr = rffi.ptradd(rffi.cast(rffi.CCHARP, struct), ofs) - fieldptr = rffi.cast(rffi.CArrayPtr(lltype.Signed), fieldptr) - fieldptr[0] = self.cast_gcref_to_int(newvalue) - # --- end of GC unsafe code --- - - @specialize.argtype(1) - def _base_do_setfield_f(self, struct, newvalue, fielddescr): - ofs = self.unpack_fielddescr(fielddescr) - # --- start of GC unsafe code (no GC operation!) --- - fieldptr = rffi.ptradd(rffi.cast(rffi.CCHARP, struct), ofs) - fieldptr = rffi.cast(rffi.CArrayPtr(longlong.FLOATSTORAGE), fieldptr) - fieldptr[0] = newvalue - # --- end of GC unsafe code --- - - bh_setfield_gc_i = _base_do_setfield_i - bh_setfield_gc_r = _base_do_setfield_r - bh_setfield_gc_f = _base_do_setfield_f - bh_setfield_raw_i = _base_do_setfield_i - bh_setfield_raw_r = _base_do_setfield_r - bh_setfield_raw_f = _base_do_setfield_f + bh_setfield_raw_i = bh_setfield_gc_i + bh_setfield_raw_f = bh_setfield_gc_f def bh_raw_store_i(self, addr, offset, newvalue, descr): - ofs, size, sign = self.unpack_arraydescr_size(descr) - items = addr + offset - for TYPE, _, itemsize in unroll_basic_sizes: - if size == itemsize: - items = rffi.cast(rffi.CArrayPtr(TYPE), items) - items[0] = rffi.cast(TYPE, newvalue) - break + ofs, size, _ = self.unpack_arraydescr_size(descr) + assert ofs == 0 # otherwise, 'descr' is not a raw length-less array + self.write_int_at_mem(addr, offset, size, newvalue) def bh_raw_store_f(self, addr, offset, newvalue, descr): - items = rffi.cast(rffi.CArrayPtr(longlong.FLOATSTORAGE), addr + offset) - items[0] = newvalue + self.write_float_at_mem(addr, offset, newvalue) def bh_raw_load_i(self, addr, offset, descr): ofs, size, sign = self.unpack_arraydescr_size(descr) @@ -725,8 +610,7 @@ return self.read_int_at_mem(addr, offset, size, sign) def bh_raw_load_f(self, addr, offset, descr): - items = rffi.cast(rffi.CArrayPtr(longlong.FLOATSTORAGE), addr + offset) - return items[0] + return self.read_float_at_mem(addr, offset) def bh_new(self, sizedescr): return self.gc_ll_descr.gc_malloc(sizedescr) @@ -734,8 +618,7 @@ def bh_new_with_vtable(self, vtable, sizedescr): res = self.gc_ll_descr.gc_malloc(sizedescr) if self.vtable_offset is not None: - as_array = rffi.cast(rffi.CArrayPtr(lltype.Signed), res) - as_array[self.vtable_offset/WORD] = vtable + self.write_int_at_mem(res, self.vtable_offset, WORD, vtable) return res def bh_new_raw_buffer(self, size): From noreply at buildbot.pypy.org Mon Sep 9 18:22:13 2013 From: noreply at buildbot.pypy.org (arigo) Date: Mon, 9 Sep 2013 18:22:13 +0200 (CEST) Subject: [pypy-commit] pypy default: Use raw_load() and raw_store() instead of custom logic for Message-ID: <20130909162213.C75BF1C02A7@cobra.cs.uni-duesseldorf.de> Author: Armin Rigo Branch: Changeset: r66865:af5e7f014b6e Date: 2013-09-09 18:12 +0200 http://bitbucket.org/pypy/pypy/changeset/af5e7f014b6e/ Log: Use raw_load() and raw_store() instead of custom logic for {read_write}_{int,ref,float}_at_mem(), with an extention that puts them on the same level as getfield/ setfield: the variant 'raw_store(GC obj, offset, GC obj)' generates a write barrier in gctransform/framework.py. 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 @@ -368,68 +368,42 @@ @specialize.argtype(1) def read_int_at_mem(self, gcref, ofs, size, sign): - # --- start of GC unsafe code (no GC operation!) --- - items = rffi.ptradd(rffi.cast(rffi.CCHARP, gcref), ofs) for STYPE, UTYPE, itemsize in unroll_basic_sizes: if size == itemsize: if sign: - items = rffi.cast(rffi.CArrayPtr(STYPE), items) - val = items[0] + val = llop.raw_load(STYPE, gcref, ofs) val = rffi.cast(lltype.Signed, val) else: - items = rffi.cast(rffi.CArrayPtr(UTYPE), items) - val = items[0] + val = llop.raw_load(UTYPE, gcref, ofs) val = rffi.cast(lltype.Signed, val) - # --- end of GC unsafe code --- return val else: raise NotImplementedError("size = %d" % size) @specialize.argtype(1) def write_int_at_mem(self, gcref, ofs, size, newvalue): - # --- start of GC unsafe code (no GC operation!) --- - items = rffi.ptradd(rffi.cast(rffi.CCHARP, gcref), ofs) for TYPE, _, itemsize in unroll_basic_sizes: if size == itemsize: - items = rffi.cast(rffi.CArrayPtr(TYPE), items) - items[0] = rffi.cast(TYPE, newvalue) - # --- end of GC unsafe code --- + newvalue = rffi.cast(TYPE, newvalue) + llop.raw_store(lltype.Void, gcref, ofs, newvalue) return else: raise NotImplementedError("size = %d" % size) def read_ref_at_mem(self, gcref, ofs): - # --- start of GC unsafe code (no GC operation!) --- - items = rffi.ptradd(rffi.cast(rffi.CCHARP, gcref), ofs) - items = rffi.cast(rffi.CArrayPtr(lltype.Signed), items) - pval = self._cast_int_to_gcref(items[0]) - # --- end of GC unsafe code --- - return pval + return llop.raw_load(llmemory.GCREF, gcref, ofs) def write_ref_at_mem(self, gcref, ofs, newvalue): - self.gc_ll_descr.do_write_barrier(gcref, newvalue) - # --- start of GC unsafe code (no GC operation!) --- - items = rffi.ptradd(rffi.cast(rffi.CCHARP, gcref), ofs) - items = rffi.cast(rffi.CArrayPtr(lltype.Signed), items) - items[0] = self.cast_gcref_to_int(newvalue) - # --- end of GC unsafe code --- + llop.raw_store(lltype.Void, gcref, ofs, newvalue) + # the write barrier is implied above @specialize.argtype(1) def read_float_at_mem(self, gcref, ofs): - # --- start of GC unsafe code (no GC operation!) --- - items = rffi.ptradd(rffi.cast(rffi.CCHARP, gcref), ofs) - items = rffi.cast(rffi.CArrayPtr(longlong.FLOATSTORAGE), items) - fval = items[0] - # --- end of GC unsafe code --- - return fval + return llop.raw_load(longlong.FLOATSTORAGE, gcref, ofs) @specialize.argtype(1) def write_float_at_mem(self, gcref, ofs, newvalue): - # --- start of GC unsafe code (no GC operation!) --- - items = rffi.ptradd(rffi.cast(rffi.CCHARP, gcref), ofs) - items = rffi.cast(rffi.CArrayPtr(longlong.FLOATSTORAGE), items) - items[0] = newvalue - # --- end of GC unsafe code --- + llop.raw_store(lltype.Void, gcref, ofs, newvalue) # ____________________________________________________________ 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 @@ -1100,7 +1100,8 @@ opname = hop.spaceop.opname v_struct = hop.spaceop.args[0] v_newvalue = hop.spaceop.args[-1] - assert opname in ('setfield', 'setarrayitem', 'setinteriorfield') + assert opname in ('setfield', 'setarrayitem', 'setinteriorfield', + 'raw_store') assert isinstance(v_newvalue.concretetype, lltype.Ptr) # XXX for some GCs the skipping if the newvalue is a constant won't be # ok 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 @@ -330,6 +330,7 @@ hop.rename('bare_' + hop.spaceop.opname) gct_setarrayitem = gct_setfield gct_setinteriorfield = gct_setfield + gct_raw_store = gct_setfield gct_getfield = default diff --git a/rpython/rtyper/llinterp.py b/rpython/rtyper/llinterp.py --- a/rpython/rtyper/llinterp.py +++ b/rpython/rtyper/llinterp.py @@ -969,6 +969,10 @@ op_raw_load.need_result_type = True def op_raw_store(self, addr, offset, value): + # XXX handle the write barrier by delegating to self.heap instead + self.op_bare_raw_store(addr, offset, value) + + def op_bare_raw_store(self, addr, offset, value): checkadr(addr) ARGTYPE = lltype.typeOf(value) if isinstance(offset, int): 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 @@ -410,8 +410,9 @@ 'raw_memclear': LLOp(), 'raw_memcopy': LLOp(), 'raw_memmove': LLOp(), - 'raw_load': LLOp(sideeffects=False), - 'raw_store': LLOp(), + 'raw_load': LLOp(sideeffects=False, canrun=True), + 'raw_store': LLOp(canrun=True), + 'bare_raw_store': LLOp(), 'stack_malloc': LLOp(), # mmh 'track_alloc_start': LLOp(), 'track_alloc_stop': LLOp(), 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 @@ -660,6 +660,26 @@ msg = ''.join(ll_msg.chars) raise LLFatalError(msg) +def op_raw_store(p, ofs, newvalue): + from rpython.rtyper.lltypesystem import rffi + TP = lltype.typeOf(p) + if TP != llmemory.Address: + assert TP == llmemory.GCREF + p = rffi.cast(llmemory.Address, p) + TVAL = lltype.typeOf(newvalue) + p = rffi.cast(rffi.CArrayPtr(TVAL), p + ofs) + p[0] = newvalue + +def op_raw_load(TVAL, p, ofs): + from rpython.rtyper.lltypesystem import rffi + TP = lltype.typeOf(p) + if TP != llmemory.Address: + assert TP == llmemory.GCREF + p = rffi.cast(llmemory.Address, p) + p = rffi.cast(rffi.CArrayPtr(TVAL), p + ofs) + return p[0] +op_raw_load.need_result_type = True + # ____________________________________________________________ def get_op_impl(opname): 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 @@ -692,6 +692,7 @@ return ( '((%(typename)s) (((char *)%(addr)s) + %(offset)s))[0] = %(value)s;' % locals()) + OP_BARE_RAW_STORE = OP_RAW_STORE def OP_RAW_LOAD(self, op): addr = self.expr(op.args[0]) From noreply at buildbot.pypy.org Mon Sep 9 18:56:19 2013 From: noreply at buildbot.pypy.org (arigo) Date: Mon, 9 Sep 2013 18:56:19 +0200 (CEST) Subject: [pypy-commit] pypy stmgc-c4: hg merge default Message-ID: <20130909165619.B1FE71C12EC@cobra.cs.uni-duesseldorf.de> Author: Armin Rigo Branch: stmgc-c4 Changeset: r66866:781dce1d3438 Date: 2013-09-09 18:25 +0200 http://bitbucket.org/pypy/pypy/changeset/781dce1d3438/ Log: hg merge default diff --git a/lib_pypy/_tkinter/__init__.py b/lib_pypy/_tkinter/__init__.py --- a/lib_pypy/_tkinter/__init__.py +++ b/lib_pypy/_tkinter/__init__.py @@ -22,6 +22,7 @@ READABLE = tklib.TCL_READABLE WRITABLE = tklib.TCL_WRITABLE EXCEPTION = tklib.TCL_EXCEPTION +DONT_WAIT = tklib.TCL_DONT_WAIT def create(screenName=None, baseName=None, className=None, interactive=False, wantobjects=False, wantTk=True, diff --git a/lib_pypy/_tkinter/app.py b/lib_pypy/_tkinter/app.py --- a/lib_pypy/_tkinter/app.py +++ b/lib_pypy/_tkinter/app.py @@ -4,7 +4,23 @@ from . import TclError from .tclobj import TclObject, FromObj, AsObj, TypeCache +import contextlib import sys +import threading +import time + + +class _DummyLock(object): + "A lock-like object that does not do anything" + def acquire(self): + pass + def release(self): + pass + def __enter__(self): + pass + def __exit__(self, *exc): + pass + def varname_converter(input): if isinstance(input, TclObject): @@ -37,17 +53,18 @@ def PythonCmd(clientData, interp, argc, argv): self = tkffi.from_handle(clientData) assert self.app.interp == interp - try: - args = [tkffi.string(arg) for arg in argv[1:argc]] - result = self.func(*args) - obj = AsObj(result) - tklib.Tcl_SetObjResult(interp, obj) - except: - self.app.errorInCmd = True - self.app.exc_info = sys.exc_info() - return tklib.TCL_ERROR - else: - return tklib.TCL_OK + with self.app._tcl_lock_released(): + try: + args = [tkffi.string(arg) for arg in argv[1:argc]] + result = self.func(*args) + obj = AsObj(result) + tklib.Tcl_SetObjResult(interp, obj) + except: + self.app.errorInCmd = True + self.app.exc_info = sys.exc_info() + return tklib.TCL_ERROR + else: + return tklib.TCL_OK @tkffi.callback("Tcl_CmdDeleteProc") def PythonCmdDelete(clientData): @@ -58,6 +75,8 @@ class TkApp(object): + _busywaitinterval = 0.02 # 20ms. + def __new__(cls, screenName, baseName, className, interactive, wantobjects, wantTk, sync, use): if not wantobjects: @@ -73,6 +92,12 @@ self.quitMainLoop = False self.errorInCmd = False + if not self.threaded: + # TCL is not thread-safe, calls needs to be serialized. + self._tcl_lock = threading.Lock() + else: + self._tcl_lock = _DummyLock() + self._typeCache = TypeCache() self._commands = {} @@ -133,6 +158,13 @@ if self.threaded and self.thread_id != tklib.Tcl_GetCurrentThread(): raise RuntimeError("Calling Tcl from different appartment") + @contextlib.contextmanager + def _tcl_lock_released(self): + "Context manager to temporarily release the tcl lock." + self._tcl_lock.release() + yield + self._tcl_lock.acquire() + def loadtk(self): # We want to guard against calling Tk_Init() multiple times err = tklib.Tcl_Eval(self.interp, "info exists tk_version") @@ -159,22 +191,25 @@ flags=tklib.TCL_LEAVE_ERR_MSG if global_only: flags |= tklib.TCL_GLOBAL_ONLY - res = tklib.Tcl_GetVar2Ex(self.interp, name1, name2, flags) - if not res: - self.raiseTclError() - assert self._wantobjects - return FromObj(self, res) + with self._tcl_lock: + res = tklib.Tcl_GetVar2Ex(self.interp, name1, name2, flags) + if not res: + self.raiseTclError() + assert self._wantobjects + return FromObj(self, res) def _setvar(self, name1, value, global_only=False): name1 = varname_converter(name1) + # XXX Acquire tcl lock??? newval = AsObj(value) flags=tklib.TCL_LEAVE_ERR_MSG if global_only: flags |= tklib.TCL_GLOBAL_ONLY - res = tklib.Tcl_SetVar2Ex(self.interp, name1, tkffi.NULL, - newval, flags) - if not res: - self.raiseTclError() + with self._tcl_lock: + res = tklib.Tcl_SetVar2Ex(self.interp, name1, tkffi.NULL, + newval, flags) + if not res: + self.raiseTclError() def _unsetvar(self, name1, name2=None, global_only=False): name1 = varname_converter(name1) @@ -183,9 +218,10 @@ flags=tklib.TCL_LEAVE_ERR_MSG if global_only: flags |= tklib.TCL_GLOBAL_ONLY - res = tklib.Tcl_UnsetVar2(self.interp, name1, name2, flags) - if res == tklib.TCL_ERROR: - self.raiseTclError() + with self._tcl_lock: + res = tklib.Tcl_UnsetVar2(self.interp, name1, name2, flags) + if res == tklib.TCL_ERROR: + self.raiseTclError() def getvar(self, name1, name2=None): return self._var_invoke(self._getvar, name1, name2) @@ -219,9 +255,10 @@ if self.threaded and self.thread_id != tklib.Tcl_GetCurrentThread(): raise NotImplementedError("Call from another thread") - res = tklib.Tcl_CreateCommand( - self.interp, cmdName, _CommandData.PythonCmd, - clientData, _CommandData.PythonCmdDelete) + with self._tcl_lock: + res = tklib.Tcl_CreateCommand( + self.interp, cmdName, _CommandData.PythonCmd, + clientData, _CommandData.PythonCmdDelete) if not res: raise TclError("can't create Tcl command") @@ -229,7 +266,8 @@ if self.threaded and self.thread_id != tklib.Tcl_GetCurrentThread(): raise NotImplementedError("Call from another thread") - res = tklib.Tcl_DeleteCommand(self.interp, cmdName) + with self._tcl_lock: + res = tklib.Tcl_DeleteCommand(self.interp, cmdName) if res == -1: raise TclError("can't delete Tcl command") @@ -256,11 +294,12 @@ tklib.Tcl_IncrRefCount(obj) objects[i] = obj - res = tklib.Tcl_EvalObjv(self.interp, argc, objects, flags) - if res == tklib.TCL_ERROR: - self.raiseTclError() - else: - result = self._callResult() + with self._tcl_lock: + res = tklib.Tcl_EvalObjv(self.interp, argc, objects, flags) + if res == tklib.TCL_ERROR: + self.raiseTclError() + else: + result = self._callResult() finally: for obj in objects: if obj: @@ -280,17 +319,19 @@ def eval(self, script): self._check_tcl_appartment() - res = tklib.Tcl_Eval(self.interp, script) - if res == tklib.TCL_ERROR: - self.raiseTclError() - return tkffi.string(tklib.Tcl_GetStringResult(self.interp)) + with self._tcl_lock: + res = tklib.Tcl_Eval(self.interp, script) + if res == tklib.TCL_ERROR: + self.raiseTclError() + return tkffi.string(tklib.Tcl_GetStringResult(self.interp)) def evalfile(self, filename): self._check_tcl_appartment() - res = tklib.Tcl_EvalFile(self.interp, filename) - if res == tklib.TCL_ERROR: - self.raiseTclError() - return tkffi.string(tklib.Tcl_GetStringResult(self.interp)) + with self._tcl_lock: + res = tklib.Tcl_EvalFile(self.interp, filename) + if res == tklib.TCL_ERROR: + self.raiseTclError() + return tkffi.string(tklib.Tcl_GetStringResult(self.interp)) def split(self, arg): if isinstance(arg, tuple): @@ -375,7 +416,10 @@ if self.threaded: result = tklib.Tcl_DoOneEvent(0) else: - raise NotImplementedError("TCL configured without threads") + with self._tcl_lock: + result = tklib.Tcl_DoOneEvent(tklib.TCL_DONT_WAIT) + if result == 0: + time.sleep(self._busywaitinterval) if result < 0: break diff --git a/lib_pypy/_tkinter/tklib.py b/lib_pypy/_tkinter/tklib.py --- a/lib_pypy/_tkinter/tklib.py +++ b/lib_pypy/_tkinter/tklib.py @@ -19,6 +19,8 @@ #define TCL_EVAL_DIRECT ... #define TCL_EVAL_GLOBAL ... +#define TCL_DONT_WAIT ... + typedef unsigned short Tcl_UniChar; typedef ... Tcl_Interp; typedef ...* Tcl_ThreadId; @@ -110,8 +112,8 @@ linklibs = ['tk85', 'tcl85'] libdirs = ['/usr/local/lib', '/usr/X11R6/lib'] else: - incdirs=['/usr/include/tcl'], - linklibs=['tcl', 'tk'], + incdirs=['/usr/include/tcl'] + linklibs=['tcl', 'tk'] libdirs = [] tklib = tkffi.verify(""" 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 @@ -373,73 +373,42 @@ @specialize.argtype(1) def read_int_at_mem(self, gcref, ofs, size, sign): - gcref = self.gc_ll_descr.do_stm_barrier(gcref, 'R') - # --- start of GC unsafe code (no GC operation!) --- - items = rffi.ptradd(rffi.cast(rffi.CCHARP, gcref), ofs) for STYPE, UTYPE, itemsize in unroll_basic_sizes: if size == itemsize: if sign: - items = rffi.cast(rffi.CArrayPtr(STYPE), items) - val = items[0] + val = llop.raw_load(STYPE, gcref, ofs) val = rffi.cast(lltype.Signed, val) else: - items = rffi.cast(rffi.CArrayPtr(UTYPE), items) - val = items[0] + val = llop.raw_load(UTYPE, gcref, ofs) val = rffi.cast(lltype.Signed, val) - # --- end of GC unsafe code --- return val else: raise NotImplementedError("size = %d" % size) @specialize.argtype(1) - def write_int_at_mem(self, gcref, ofs, size, sign, newvalue): - gcref = self.gc_ll_descr.do_stm_barrier(gcref, 'W') - # --- start of GC unsafe code (no GC operation!) --- - items = rffi.ptradd(rffi.cast(rffi.CCHARP, gcref), ofs) + def write_int_at_mem(self, gcref, ofs, size, newvalue): for TYPE, _, itemsize in unroll_basic_sizes: if size == itemsize: - items = rffi.cast(rffi.CArrayPtr(TYPE), items) - items[0] = rffi.cast(TYPE, newvalue) - # --- end of GC unsafe code --- + newvalue = rffi.cast(TYPE, newvalue) + llop.raw_store(lltype.Void, gcref, ofs, newvalue) return else: raise NotImplementedError("size = %d" % size) def read_ref_at_mem(self, gcref, ofs): - gcref = self.gc_ll_descr.do_stm_barrier(gcref, 'R') - # --- start of GC unsafe code (no GC operation!) --- - items = rffi.ptradd(rffi.cast(rffi.CCHARP, gcref), ofs) - items = rffi.cast(rffi.CArrayPtr(lltype.Signed), items) - pval = self._cast_int_to_gcref(items[0]) - # --- end of GC unsafe code --- - return pval + return llop.raw_load(llmemory.GCREF, gcref, ofs) def write_ref_at_mem(self, gcref, ofs, newvalue): - gcref = self.gc_ll_descr.do_stm_barrier(gcref, 'W') - # --- start of GC unsafe code (no GC operation!) --- - items = rffi.ptradd(rffi.cast(rffi.CCHARP, gcref), ofs) - items = rffi.cast(rffi.CArrayPtr(lltype.Signed), items) - items[0] = self.cast_gcref_to_int(newvalue) - # --- end of GC unsafe code --- + llop.raw_store(lltype.Void, gcref, ofs, newvalue) + # the write barrier is implied above @specialize.argtype(1) def read_float_at_mem(self, gcref, ofs): - gcref = self.gc_ll_descr.do_stm_barrier(gcref, 'R') - # --- start of GC unsafe code (no GC operation!) --- - items = rffi.ptradd(rffi.cast(rffi.CCHARP, gcref), ofs) - items = rffi.cast(rffi.CArrayPtr(longlong.FLOATSTORAGE), items) - fval = items[0] - # --- end of GC unsafe code --- - return fval + return llop.raw_load(longlong.FLOATSTORAGE, gcref, ofs) @specialize.argtype(1) def write_float_at_mem(self, gcref, ofs, newvalue): - gcref = self.gc_ll_descr.do_stm_barrier(gcref, 'W') - # --- start of GC unsafe code (no GC operation!) --- - items = rffi.ptradd(rffi.cast(rffi.CCHARP, gcref), ofs) - items = rffi.cast(rffi.CArrayPtr(longlong.FLOATSTORAGE), items) - items[0] = newvalue - # --- end of GC unsafe code --- + llop.raw_store(lltype.Void, gcref, ofs, newvalue) # ____________________________________________________________ @@ -449,7 +418,7 @@ """ descr = self.gc_ll_descr.getframedescrs(self).arraydescr ofs = self.unpack_arraydescr(descr) - self.write_int_at_mem(newframe, ofs + index, WORD, 1, value) + self.write_int_at_mem(newframe, ofs + index, WORD, value) def set_ref_value(self, newframe, index, value): descr = self.gc_ll_descr.getframedescrs(self).arraydescr @@ -476,9 +445,8 @@ def bh_arraylen_gc(self, array, arraydescr): assert isinstance(arraydescr, ArrayDescr) - array = self.gc_ll_descr.do_stm_barrier(array, 'R') ofs = arraydescr.lendescr.offset - return rffi.cast(rffi.CArrayPtr(lltype.Signed), array)[ofs/WORD] + return self.read_int_at_mem(array, ofs, WORD, 1) @specialize.argtype(1) def bh_getarrayitem_gc_i(self, gcref, itemindex, arraydescr): @@ -499,8 +467,7 @@ @specialize.argtype(1) def bh_setarrayitem_gc_i(self, gcref, itemindex, newvalue, arraydescr): ofs, size, sign = self.unpack_arraydescr_size(arraydescr) - self.write_int_at_mem(gcref, ofs + itemindex * size, size, sign, - newvalue) + self.write_int_at_mem(gcref, ofs + itemindex * size, size, newvalue) def bh_setarrayitem_gc_r(self, gcref, itemindex, newvalue, arraydescr): ofs = self.unpack_arraydescr(arraydescr) @@ -520,231 +487,101 @@ def bh_getinteriorfield_gc_i(self, gcref, itemindex, descr): assert isinstance(descr, InteriorFieldDescr) - arraydescr = descr.arraydescr - ofs, size, _ = self.unpack_arraydescr_size(arraydescr) - ofs += descr.fielddescr.offset - fieldsize = descr.fielddescr.field_size - sign = descr.fielddescr.is_field_signed() - fullofs = itemindex * size + ofs - gcref = self.gc_ll_descr.do_stm_barrier(gcref, 'R') - # --- start of GC unsafe code (no GC operation!) --- - items = rffi.ptradd(rffi.cast(rffi.CCHARP, gcref), fullofs) - for STYPE, UTYPE, itemsize in unroll_basic_sizes: - if fieldsize == itemsize: - if sign: - item = rffi.cast(rffi.CArrayPtr(STYPE), items) - val = item[0] - val = rffi.cast(lltype.Signed, val) - else: - item = rffi.cast(rffi.CArrayPtr(UTYPE), items) - val = item[0] - val = rffi.cast(lltype.Signed, val) - # --- end of GC unsafe code --- - return val - else: - raise NotImplementedError("size = %d" % fieldsize) + ofs, size, _ = self.unpack_arraydescr_size(descr.arraydescr) + fldofs, fldsize, sign = self.unpack_fielddescr_size(descr.fielddescr) + ofs += itemindex * size + fldofs + return self.read_int_at_mem(gcref, ofs, fldsize, sign) def bh_getinteriorfield_gc_r(self, gcref, itemindex, descr): assert isinstance(descr, InteriorFieldDescr) - arraydescr = descr.arraydescr - ofs, size, _ = self.unpack_arraydescr_size(arraydescr) + ofs, size, _ = self.unpack_arraydescr_size(descr.arraydescr) ofs += descr.fielddescr.offset - gcref = self.gc_ll_descr.do_stm_barrier(gcref, 'R') - # --- start of GC unsafe code (no GC operation!) --- - items = rffi.ptradd(rffi.cast(rffi.CCHARP, gcref), ofs + - size * itemindex) - items = rffi.cast(rffi.CArrayPtr(lltype.Signed), items) - pval = self._cast_int_to_gcref(items[0]) - # --- end of GC unsafe code --- - return pval + fullofs = itemindex * size + ofs + return self.read_ref_at_mem(gcref, fullofs) def bh_getinteriorfield_gc_f(self, gcref, itemindex, descr): assert isinstance(descr, InteriorFieldDescr) - arraydescr = descr.arraydescr - ofs, size, _ = self.unpack_arraydescr_size(arraydescr) + ofs, size, _ = self.unpack_arraydescr_size(descr.arraydescr) ofs += descr.fielddescr.offset - gcref = self.gc_ll_descr.do_stm_barrier(gcref, 'R') - # --- start of GC unsafe code (no GC operation!) --- - items = rffi.ptradd(rffi.cast(rffi.CCHARP, gcref), ofs + - size * itemindex) - items = rffi.cast(rffi.CArrayPtr(longlong.FLOATSTORAGE), items) - fval = items[0] - # --- end of GC unsafe code --- - return fval + fullofs = itemindex * size + ofs + return self.read_float_at_mem(gcref, fullofs) - def bh_setinteriorfield_gc_i(self, gcref, itemindex, value, descr): + def bh_setinteriorfield_gc_i(self, gcref, itemindex, newvalue, descr): assert isinstance(descr, InteriorFieldDescr) - arraydescr = descr.arraydescr - ofs, size, _ = self.unpack_arraydescr_size(arraydescr) - ofs += descr.fielddescr.offset - fieldsize = descr.fielddescr.field_size - ofs = itemindex * size + ofs - gcref = self.gc_ll_descr.do_stm_barrier(gcref, 'W') - # --- start of GC unsafe code (no GC operation!) --- - items = rffi.ptradd(rffi.cast(rffi.CCHARP, gcref), ofs) - for TYPE, _, itemsize in unroll_basic_sizes: - if fieldsize == itemsize: - items = rffi.cast(rffi.CArrayPtr(TYPE), items) - items[0] = rffi.cast(TYPE, value) - # --- end of GC unsafe code --- - return - else: - raise NotImplementedError("size = %d" % fieldsize) + ofs, size, _ = self.unpack_arraydescr_size(descr.arraydescr) + fldofs, fldsize, _ = self.unpack_fielddescr_size(descr.fielddescr) + ofs += itemindex * size + fldofs + self.write_int_at_mem(gcref, ofs, fldsize, newvalue) def bh_setinteriorfield_gc_r(self, gcref, itemindex, newvalue, descr): assert isinstance(descr, InteriorFieldDescr) - arraydescr = descr.arraydescr - ofs, size, _ = self.unpack_arraydescr_size(arraydescr) - ofs += descr.fielddescr.offset - gcref = self.gc_ll_descr.do_stm_barrier(gcref, 'W') - #self.gc_ll_descr.do_write_barrier(gcref, newvalue) - # --- start of GC unsafe code (no GC operation!) --- - items = rffi.ptradd(rffi.cast(rffi.CCHARP, gcref), - ofs + size * itemindex) - items = rffi.cast(rffi.CArrayPtr(lltype.Signed), items) - items[0] = self.cast_gcref_to_int(newvalue) - # --- end of GC unsafe code --- + ofs, size, _ = self.unpack_arraydescr_size(descr.arraydescr) + ofs += itemindex * size + descr.fielddescr.offset + self.write_ref_at_mem(gcref, ofs, newvalue) def bh_setinteriorfield_gc_f(self, gcref, itemindex, newvalue, descr): assert isinstance(descr, InteriorFieldDescr) - arraydescr = descr.arraydescr - ofs, size, _ = self.unpack_arraydescr_size(arraydescr) - ofs += descr.fielddescr.offset - gcref = self.gc_ll_descr.do_stm_barrier(gcref, 'W') - # --- start of GC unsafe code (no GC operation!) --- - items = rffi.ptradd(rffi.cast(rffi.CCHARP, gcref), - ofs + size * itemindex) - items = rffi.cast(rffi.CArrayPtr(longlong.FLOATSTORAGE), items) - items[0] = newvalue - # --- end of GC unsafe code --- + ofs, size, _ = self.unpack_arraydescr_size(descr.arraydescr) + ofs += itemindex * size + descr.fielddescr.offset + self.write_float_at_mem(gcref, ofs, newvalue) def bh_strlen(self, string): - string = self.gc_ll_descr.do_stm_barrier(string, 'R') s = lltype.cast_opaque_ptr(lltype.Ptr(rstr.STR), string) return len(s.chars) def bh_unicodelen(self, string): - string = self.gc_ll_descr.do_stm_barrier(string, 'R') u = lltype.cast_opaque_ptr(lltype.Ptr(rstr.UNICODE), string) return len(u.chars) def bh_strgetitem(self, string, index): - string = self.gc_ll_descr.do_stm_barrier(string, 'R') s = lltype.cast_opaque_ptr(lltype.Ptr(rstr.STR), string) return ord(s.chars[index]) def bh_unicodegetitem(self, string, index): - string = self.gc_ll_descr.do_stm_barrier(string, 'R') u = lltype.cast_opaque_ptr(lltype.Ptr(rstr.UNICODE), string) return ord(u.chars[index]) @specialize.argtype(1) - def _base_do_getfield_i(self, struct, fielddescr): + def bh_getfield_gc_i(self, struct, fielddescr): ofs, size, sign = self.unpack_fielddescr_size(fielddescr) - struct = self.gc_ll_descr.do_stm_barrier(struct, 'R') - # --- start of GC unsafe code (no GC operation!) --- - fieldptr = rffi.ptradd(rffi.cast(rffi.CCHARP, struct), ofs) - for STYPE, UTYPE, itemsize in unroll_basic_sizes: - if size == itemsize: - # Note that in the common case where size==sizeof(Signed), - # both cases of what follows are doing the same thing. - # But gcc is clever enough to figure this out :-) - if sign: - val = rffi.cast(rffi.CArrayPtr(STYPE), fieldptr)[0] - val = rffi.cast(lltype.Signed, val) - else: - val = rffi.cast(rffi.CArrayPtr(UTYPE), fieldptr)[0] - val = rffi.cast(lltype.Signed, val) - # --- end of GC unsafe code --- - return val - else: - raise NotImplementedError("size = %d" % size) + return self.read_int_at_mem(struct, ofs, size, sign) + + def bh_getfield_gc_r(self, struct, fielddescr): + ofs = self.unpack_fielddescr(fielddescr) + return self.read_ref_at_mem(struct, ofs) @specialize.argtype(1) - def _base_do_getfield_r(self, struct, fielddescr): + def bh_getfield_gc_f(self, struct, fielddescr): ofs = self.unpack_fielddescr(fielddescr) - struct = self.gc_ll_descr.do_stm_barrier(struct, 'R') - # --- start of GC unsafe code (no GC operation!) --- - fieldptr = rffi.ptradd(rffi.cast(rffi.CCHARP, struct), ofs) - pval = rffi.cast(rffi.CArrayPtr(lltype.Signed), fieldptr)[0] - pval = self._cast_int_to_gcref(pval) - # --- end of GC unsafe code --- - return pval + return self.read_float_at_mem(struct, ofs) + + bh_getfield_raw_i = bh_getfield_gc_i + bh_getfield_raw_f = bh_getfield_gc_f @specialize.argtype(1) - def _base_do_getfield_f(self, struct, fielddescr): + def bh_setfield_gc_i(self, struct, newvalue, fielddescr): + ofs, size, _ = self.unpack_fielddescr_size(fielddescr) + self.write_int_at_mem(struct, ofs, size, newvalue) + + def bh_setfield_gc_r(self, struct, newvalue, fielddescr): ofs = self.unpack_fielddescr(fielddescr) - struct = self.gc_ll_descr.do_stm_barrier(struct, 'R') - # --- start of GC unsafe code (no GC operation!) --- - fieldptr = rffi.ptradd(rffi.cast(rffi.CCHARP, struct), ofs) - fval = rffi.cast(rffi.CArrayPtr(longlong.FLOATSTORAGE), fieldptr)[0] - # --- end of GC unsafe code --- - return fval - - bh_getfield_gc_i = _base_do_getfield_i - bh_getfield_gc_r = _base_do_getfield_r - bh_getfield_gc_f = _base_do_getfield_f - bh_getfield_raw_i = _base_do_getfield_i - bh_getfield_raw_r = _base_do_getfield_r - bh_getfield_raw_f = _base_do_getfield_f + self.write_ref_at_mem(struct, ofs, newvalue) @specialize.argtype(1) - def _base_do_setfield_i(self, struct, newvalue, fielddescr): - ofs, size, sign = self.unpack_fielddescr_size(fielddescr) - struct = self.gc_ll_descr.do_stm_barrier(struct, 'W') - # --- start of GC unsafe code (no GC operation!) --- - fieldptr = rffi.ptradd(rffi.cast(rffi.CCHARP, struct), ofs) - for TYPE, _, itemsize in unroll_basic_sizes: - if size == itemsize: - fieldptr = rffi.cast(rffi.CArrayPtr(TYPE), fieldptr) - fieldptr[0] = rffi.cast(TYPE, newvalue) - # --- end of GC unsafe code --- - return - else: - raise NotImplementedError("size = %d" % size) + def bh_setfield_gc_f(self, struct, newvalue, fielddescr): + ofs = self.unpack_fielddescr(fielddescr) + self.write_float_at_mem(struct, ofs, newvalue) - @specialize.argtype(1) - def _base_do_setfield_r(self, struct, newvalue, fielddescr): - ofs = self.unpack_fielddescr(fielddescr) - assert lltype.typeOf(struct) is not lltype.Signed, ( - "can't handle write barriers for setfield_raw") - struct = self.gc_ll_descr.do_stm_barrier(struct, 'W') - #self.gc_ll_descr.do_write_barrier(struct, newvalue) - # --- start of GC unsafe code (no GC operation!) --- - fieldptr = rffi.ptradd(rffi.cast(rffi.CCHARP, struct), ofs) - fieldptr = rffi.cast(rffi.CArrayPtr(lltype.Signed), fieldptr) - fieldptr[0] = self.cast_gcref_to_int(newvalue) - # --- end of GC unsafe code --- - - @specialize.argtype(1) - def _base_do_setfield_f(self, struct, newvalue, fielddescr): - ofs = self.unpack_fielddescr(fielddescr) - struct = self.gc_ll_descr.do_stm_barrier(struct, 'W') - # --- start of GC unsafe code (no GC operation!) --- - fieldptr = rffi.ptradd(rffi.cast(rffi.CCHARP, struct), ofs) - fieldptr = rffi.cast(rffi.CArrayPtr(longlong.FLOATSTORAGE), fieldptr) - fieldptr[0] = newvalue - # --- end of GC unsafe code --- - - bh_setfield_gc_i = _base_do_setfield_i - bh_setfield_gc_r = _base_do_setfield_r - bh_setfield_gc_f = _base_do_setfield_f - bh_setfield_raw_i = _base_do_setfield_i - bh_setfield_raw_r = _base_do_setfield_r - bh_setfield_raw_f = _base_do_setfield_f + bh_setfield_raw_i = bh_setfield_gc_i + bh_setfield_raw_f = bh_setfield_gc_f def bh_raw_store_i(self, addr, offset, newvalue, descr): - ofs, size, sign = self.unpack_arraydescr_size(descr) - items = addr + offset - for TYPE, _, itemsize in unroll_basic_sizes: - if size == itemsize: - items = rffi.cast(rffi.CArrayPtr(TYPE), items) - items[0] = rffi.cast(TYPE, newvalue) - break + ofs, size, _ = self.unpack_arraydescr_size(descr) + assert ofs == 0 # otherwise, 'descr' is not a raw length-less array + self.write_int_at_mem(addr, offset, size, newvalue) def bh_raw_store_f(self, addr, offset, newvalue, descr): - items = rffi.cast(rffi.CArrayPtr(longlong.FLOATSTORAGE), addr + offset) - items[0] = newvalue + self.write_float_at_mem(addr, offset, newvalue) def bh_raw_load_i(self, addr, offset, descr): ofs, size, sign = self.unpack_arraydescr_size(descr) @@ -752,8 +589,7 @@ return self.read_int_at_mem(addr, offset, size, sign) def bh_raw_load_f(self, addr, offset, descr): - items = rffi.cast(rffi.CArrayPtr(longlong.FLOATSTORAGE), addr + offset) - return items[0] + return self.read_float_at_mem(addr, offset) def bh_new(self, sizedescr): return self.gc_ll_descr.gc_malloc(sizedescr) @@ -761,17 +597,13 @@ def bh_new_with_vtable(self, vtable, sizedescr): res = self.gc_ll_descr.gc_malloc(sizedescr) if self.vtable_offset is not None: - assert not self.gc_ll_descr.stm - res = self.gc_ll_descr.do_stm_barrier(res, 'W') - as_array = rffi.cast(rffi.CArrayPtr(lltype.Signed), res) - as_array[self.vtable_offset/WORD] = vtable + self.write_int_at_mem(res, self.vtable_offset, WORD, vtable) return res def bh_new_raw_buffer(self, size): return lltype.malloc(rffi.CCHARP.TO, size, flavor='raw') def bh_classof(self, struct): - struct = self.gc_ll_descr.do_stm_barrier(struct, 'R') struct = lltype.cast_opaque_ptr(rclass.OBJECTPTR, struct) result_adr = llmemory.cast_ptr_to_adr(struct.typeptr) return heaptracker.adr2int(result_adr) @@ -786,25 +618,19 @@ return self.gc_ll_descr.gc_malloc_unicode(length) def bh_strsetitem(self, string, index, newvalue): - string = self.gc_ll_descr.do_stm_barrier(string, 'W') s = lltype.cast_opaque_ptr(lltype.Ptr(rstr.STR), string) s.chars[index] = chr(newvalue) def bh_unicodesetitem(self, string, index, newvalue): - string = self.gc_ll_descr.do_stm_barrier(string, 'W') u = lltype.cast_opaque_ptr(lltype.Ptr(rstr.UNICODE), string) u.chars[index] = unichr(newvalue) def bh_copystrcontent(self, src, dst, srcstart, dststart, length): - src = self.gc_ll_descr.do_stm_barrier(src, 'R') - dst = self.gc_ll_descr.do_stm_barrier(dst, 'W') src = lltype.cast_opaque_ptr(lltype.Ptr(rstr.STR), src) dst = lltype.cast_opaque_ptr(lltype.Ptr(rstr.STR), dst) rstr.copy_string_contents(src, dst, srcstart, dststart, length) def bh_copyunicodecontent(self, src, dst, srcstart, dststart, length): - src = self.gc_ll_descr.do_stm_barrier(src, 'R') - dst = self.gc_ll_descr.do_stm_barrier(dst, 'W') src = lltype.cast_opaque_ptr(lltype.Ptr(rstr.UNICODE), src) dst = lltype.cast_opaque_ptr(lltype.Ptr(rstr.UNICODE), dst) rstr.copy_unicode_contents(src, dst, srcstart, dststart, length) 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 @@ -740,7 +740,7 @@ 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): + def _check_frame_depth(self, mc, gcmap): """ check if the frame is of enough depth to follow this bridge. Otherwise reallocate the frame in a helper. There are other potential solutions @@ -748,17 +748,11 @@ """ descrs = self.cpu.gc_ll_descr.getframedescrs(self.cpu) ofs = self.cpu.unpack_fielddescr(descrs.arraydescr.lendescr) - if expected_size == -1: - mc.CMP_bi(ofs, 0xffffff) - else: - mc.CMP_bi(ofs, expected_size) + mc.CMP_bi(ofs, 0xffffff) # force writing 32 bit stack_check_cmp_ofs = mc.get_relative_pos() - 4 mc.J_il8(rx86.Conditions['GE'], 0) jg_location = mc.get_relative_pos() - if expected_size == -1: - mc.MOV_si(WORD, 0xffffff) - else: - mc.MOV_si(WORD, expected_size) + mc.MOV_si(WORD, 0xffffff) # force writing 32 bit ofs2 = mc.get_relative_pos() - 4 self.push_gcmap(mc, gcmap, mov=True) mc.CALL(imm(self._frame_realloc_slowpath)) 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 @@ -1119,7 +1119,8 @@ opname = hop.spaceop.opname v_struct = hop.spaceop.args[0] v_newvalue = hop.spaceop.args[-1] - assert opname in ('setfield', 'setarrayitem', 'setinteriorfield') + assert opname in ('setfield', 'setarrayitem', 'setinteriorfield', + 'raw_store') assert isinstance(v_newvalue.concretetype, lltype.Ptr) # XXX for some GCs the skipping if the newvalue is a constant won't be # ok 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 @@ -330,6 +330,7 @@ hop.rename('bare_' + hop.spaceop.opname) gct_setarrayitem = gct_setfield gct_setinteriorfield = gct_setfield + gct_raw_store = gct_setfield gct_getfield = default diff --git a/rpython/rlib/rstring.py b/rpython/rlib/rstring.py --- a/rpython/rlib/rstring.py +++ b/rpython/rlib/rstring.py @@ -149,6 +149,7 @@ @specialize.argtype(0) + at jit.elidable def replace(input, sub, by, maxsplit=-1): if isinstance(input, str): assert isinstance(sub, str) diff --git a/rpython/rtyper/llinterp.py b/rpython/rtyper/llinterp.py --- a/rpython/rtyper/llinterp.py +++ b/rpython/rtyper/llinterp.py @@ -1025,6 +1025,10 @@ op_raw_load.need_result_type = True def op_raw_store(self, addr, offset, value): + # XXX handle the write barrier by delegating to self.heap instead + self.op_bare_raw_store(addr, offset, value) + + def op_bare_raw_store(self, addr, offset, value): checkadr(addr) ARGTYPE = lltype.typeOf(value) if isinstance(offset, int): 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 @@ -461,8 +461,9 @@ 'raw_memclear': LLOp(), 'raw_memcopy': LLOp(), 'raw_memmove': LLOp(), - 'raw_load': LLOp(sideeffects=False), - 'raw_store': LLOp(), + 'raw_load': LLOp(sideeffects=False, canrun=True), + 'raw_store': LLOp(canrun=True), + 'bare_raw_store': LLOp(), 'stack_malloc': LLOp(), # mmh 'track_alloc_start': LLOp(), 'track_alloc_stop': LLOp(), 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 @@ -678,6 +678,26 @@ def op_stm_get_tid(x): raise NotImplementedError +def op_raw_store(p, ofs, newvalue): + from rpython.rtyper.lltypesystem import rffi + TP = lltype.typeOf(p) + if TP != llmemory.Address: + assert TP == llmemory.GCREF + p = rffi.cast(llmemory.Address, p) + TVAL = lltype.typeOf(newvalue) + p = rffi.cast(rffi.CArrayPtr(TVAL), p + ofs) + p[0] = newvalue + +def op_raw_load(TVAL, p, ofs): + from rpython.rtyper.lltypesystem import rffi + TP = lltype.typeOf(p) + if TP != llmemory.Address: + assert TP == llmemory.GCREF + p = rffi.cast(llmemory.Address, p) + p = rffi.cast(rffi.CArrayPtr(TVAL), p + ofs) + return p[0] +op_raw_load.need_result_type = True + # ____________________________________________________________ def get_op_impl(opname): 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 @@ -744,6 +744,7 @@ return ( '((%(typename)s) (((char *)%(addr)s) + %(offset)s))[0] = %(value)s;' % locals()) + OP_BARE_RAW_STORE = OP_RAW_STORE def OP_RAW_LOAD(self, op): addr = self.expr(op.args[0]) From noreply at buildbot.pypy.org Mon Sep 9 18:56:21 2013 From: noreply at buildbot.pypy.org (arigo) Date: Mon, 9 Sep 2013 18:56:21 +0200 (CEST) Subject: [pypy-commit] pypy stmgc-c4: Add raw_load and raw_store here, to generate the correct barriers Message-ID: <20130909165621.095551C12EC@cobra.cs.uni-duesseldorf.de> Author: Armin Rigo Branch: stmgc-c4 Changeset: r66867:1b6f11c55022 Date: 2013-09-09 18:28 +0200 http://bitbucket.org/pypy/pypy/changeset/1b6f11c55022/ Log: Add raw_load and raw_store here, to generate the correct barriers when applied on GC objects. diff --git a/rpython/translator/stm/inevitable.py b/rpython/translator/stm/inevitable.py --- a/rpython/translator/stm/inevitable.py +++ b/rpython/translator/stm/inevitable.py @@ -25,8 +25,8 @@ if opname.startswith('stm_'): ALWAYS_ALLOW_OPERATIONS.add(opname) -GETTERS = set(['getfield', 'getarrayitem', 'getinteriorfield']) -SETTERS = set(['setfield', 'setarrayitem', 'setinteriorfield']) +GETTERS = set(['getfield', 'getarrayitem', 'getinteriorfield', 'raw_load']) +SETTERS = set(['setfield', 'setarrayitem', 'setinteriorfield', 'raw_store']) MALLOCS = set(['malloc', 'malloc_varsize', 'malloc_nonmovable', 'malloc_nonmovable_varsize']) # ____________________________________________________________ diff --git a/rpython/translator/stm/writebarrier.py b/rpython/translator/stm/writebarrier.py --- a/rpython/translator/stm/writebarrier.py +++ b/rpython/translator/stm/writebarrier.py @@ -23,7 +23,7 @@ if op.opname in ('getfield', 'setfield'): STRUCT = op.args[0].concretetype.TO return STRUCT._immutable_field(op.args[1].value) - if op.opname in ('getarrayitem', 'setarrayitem'): + if op.opname in ('getarrayitem', 'setarrayitem', 'raw_load', 'raw_store'): ARRAY = op.args[0].concretetype.TO return ARRAY._immutable_field() if op.opname == 'getinteriorfield': @@ -70,7 +70,7 @@ expand_comparison = set() for op in self.block.operations: is_getter = (op.opname in ('getfield', 'getarrayitem', - 'getinteriorfield') and + 'getinteriorfield', 'raw_load') and op.result.concretetype is not lltype.Void and is_gc_ptr(op.args[0].concretetype)) @@ -93,7 +93,7 @@ wants_a_barrier[op] = 'R' elif (op.opname in ('setfield', 'setarrayitem', - 'setinteriorfield') and + 'setinteriorfield', 'raw_store') and op.args[-1].concretetype is not lltype.Void and is_gc_ptr(op.args[0].concretetype)): # setfields need a regular write barrier From noreply at buildbot.pypy.org Mon Sep 9 18:56:22 2013 From: noreply at buildbot.pypy.org (arigo) Date: Mon, 9 Sep 2013 18:56:22 +0200 (CEST) Subject: [pypy-commit] pypy stmgc-c4: Fixes: in raw_load/raw_store, we don't know what kind of type the 1st argument has. It could be a GCREF, or a Signed or an Message-ID: <20130909165622.4F8871C12EC@cobra.cs.uni-duesseldorf.de> Author: Armin Rigo Branch: stmgc-c4 Changeset: r66868:ffe7dd8b3850 Date: 2013-09-09 18:54 +0200 http://bitbucket.org/pypy/pypy/changeset/ffe7dd8b3850/ Log: Fixes: in raw_load/raw_store, we don't know what kind of type the 1st argument has. It could be a GCREF, or a Signed or an Address. diff --git a/rpython/translator/stm/inevitable.py b/rpython/translator/stm/inevitable.py --- a/rpython/translator/stm/inevitable.py +++ b/rpython/translator/stm/inevitable.py @@ -36,7 +36,10 @@ # If it is a RAW pointer, and it is a read from a non-immutable place, # and it doesn't use the hint 'stm_dont_track_raw_accesses', then they # turn inevitable. - S = op.args[0].concretetype.TO + TYPE = op.args[0].concretetype + if not isinstance(TYPE, lltype.Ptr): + return True # raw_load or raw_store with a number or address + S = TYPE.TO if S._gckind == 'gc': return False if is_immutable(op): diff --git a/rpython/translator/stm/writebarrier.py b/rpython/translator/stm/writebarrier.py --- a/rpython/translator/stm/writebarrier.py +++ b/rpython/translator/stm/writebarrier.py @@ -23,7 +23,7 @@ if op.opname in ('getfield', 'setfield'): STRUCT = op.args[0].concretetype.TO return STRUCT._immutable_field(op.args[1].value) - if op.opname in ('getarrayitem', 'setarrayitem', 'raw_load', 'raw_store'): + if op.opname in ('getarrayitem', 'setarrayitem'): ARRAY = op.args[0].concretetype.TO return ARRAY._immutable_field() if op.opname == 'getinteriorfield': @@ -32,6 +32,8 @@ if op.opname == 'setinteriorfield': OUTER = op.args[0].concretetype.TO return OUTER._immutable_interiorfield(unwraplist(op.args[1:-1])) + if op.opname in ('raw_load', 'raw_store'): + return False raise AssertionError(op) def needs_barrier(frm, to): From noreply at buildbot.pypy.org Mon Sep 9 19:13:41 2013 From: noreply at buildbot.pypy.org (arigo) Date: Mon, 9 Sep 2013 19:13:41 +0200 (CEST) Subject: [pypy-commit] pypy default: Fix: allow other types too, e.g. an AddressAsInt instance. Message-ID: <20130909171341.DFABD1C026D@cobra.cs.uni-duesseldorf.de> Author: Armin Rigo Branch: Changeset: r66869:6aade584984f Date: 2013-09-09 19:13 +0200 http://bitbucket.org/pypy/pypy/changeset/6aade584984f/ Log: Fix: allow other types too, e.g. an AddressAsInt instance. 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 @@ -663,9 +663,7 @@ def op_raw_store(p, ofs, newvalue): from rpython.rtyper.lltypesystem import rffi TP = lltype.typeOf(p) - if TP != llmemory.Address: - assert TP == llmemory.GCREF - p = rffi.cast(llmemory.Address, p) + p = rffi.cast(llmemory.Address, p) TVAL = lltype.typeOf(newvalue) p = rffi.cast(rffi.CArrayPtr(TVAL), p + ofs) p[0] = newvalue @@ -673,9 +671,7 @@ def op_raw_load(TVAL, p, ofs): from rpython.rtyper.lltypesystem import rffi TP = lltype.typeOf(p) - if TP != llmemory.Address: - assert TP == llmemory.GCREF - p = rffi.cast(llmemory.Address, p) + p = rffi.cast(llmemory.Address, p) p = rffi.cast(rffi.CArrayPtr(TVAL), p + ofs) return p[0] op_raw_load.need_result_type = True From noreply at buildbot.pypy.org Mon Sep 9 19:16:47 2013 From: noreply at buildbot.pypy.org (arigo) Date: Mon, 9 Sep 2013 19:16:47 +0200 (CEST) Subject: [pypy-commit] pypy stmgc-c4: The indirect_call() going to assembler code forces the transaction to Message-ID: <20130909171647.6C5B21C02A7@cobra.cs.uni-duesseldorf.de> Author: Armin Rigo Branch: stmgc-c4 Changeset: r66870:ff868bef7ee0 Date: 2013-09-09 19:09 +0200 http://bitbucket.org/pypy/pypy/changeset/ff868bef7ee0/ Log: The indirect_call() going to assembler code forces the transaction to become inevitable. The only way I can think of to avoid this is to add a new operation. 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 @@ -252,7 +252,13 @@ else: assert kind == history.REF self.set_ref_value(ll_frame, num, arg) - ll_frame = func(ll_frame) + # This is the line that calls the assembler code. + # 'func(ll_frame)' would work here too, producing an + # indirect_call(func, ll_frame, None). The main difference + # is that 'jit_assembler_call' is a hint to STM to not + # force the transaction to become inevitable. + ll_frame = llop.jit_assembler_call(llmemory.GCREF, func, + ll_frame) finally: if not self.translate_support_code: LLInterpreter.current_interpreter = prev_interpreter 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 @@ -507,6 +507,7 @@ 'get_write_barrier_from_array_failing_case': LLOp(sideeffects=False), 'gc_get_type_info_group': LLOp(sideeffects=False), 'll_read_timestamp': LLOp(canrun=True), + 'jit_assembler_call': LLOp(canrun=True), # similar to an 'indirect_call' # __________ GC operations __________ 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 @@ -698,6 +698,9 @@ return p[0] op_raw_load.need_result_type = True +def op_jit_assembler_call(funcptr, *args): + return funcptr(*args) + # ____________________________________________________________ def get_op_impl(opname): 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 @@ -445,14 +445,10 @@ return self.generic_call(fn.concretetype, self.expr(fn), op.args[1:-1], op.result, op.args[-1].value) - def OP_ADR_CALL(self, op): - ARGTYPES = [v.concretetype for v in op.args[1:]] - RESTYPE = op.result.concretetype - FUNC = Ptr(FuncType(ARGTYPES, RESTYPE)) - typename = self.db.gettype(FUNC) - fnaddr = op.args[0] - fnexpr = '((%s)%s)' % (cdecl(typename, ''), self.expr(fnaddr)) - return self.generic_call(FUNC, fnexpr, op.args[1:], op.result) + def OP_JIT_ASSEMBLER_CALL(self, op): + fn = op.args[0] + return self.generic_call(fn.concretetype, self.expr(fn), + op.args[1:], op.result) def OP_JIT_CONDITIONAL_CALL(self, op): return 'abort(); /* jit_conditional_call */' diff --git a/rpython/translator/stm/inevitable.py b/rpython/translator/stm/inevitable.py --- a/rpython/translator/stm/inevitable.py +++ b/rpython/translator/stm/inevitable.py @@ -18,6 +18,7 @@ 'weakref_create', 'weakref_deref', 'stm_threadlocalref_get', 'stm_threadlocalref_set', 'stm_threadlocalref_count', 'stm_threadlocalref_addr', + 'jit_assembler_call', ]) ALWAYS_ALLOW_OPERATIONS |= set(lloperation.enum_tryfold_ops()) From noreply at buildbot.pypy.org Mon Sep 9 19:16:48 2013 From: noreply at buildbot.pypy.org (arigo) Date: Mon, 9 Sep 2013 19:16:48 +0200 (CEST) Subject: [pypy-commit] pypy stmgc-c4: hg merge default Message-ID: <20130909171648.AE04A1C02A7@cobra.cs.uni-duesseldorf.de> Author: Armin Rigo Branch: stmgc-c4 Changeset: r66871:a206090d8a53 Date: 2013-09-09 19:13 +0200 http://bitbucket.org/pypy/pypy/changeset/a206090d8a53/ Log: hg merge default 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 @@ -681,9 +681,7 @@ def op_raw_store(p, ofs, newvalue): from rpython.rtyper.lltypesystem import rffi TP = lltype.typeOf(p) - if TP != llmemory.Address: - assert TP == llmemory.GCREF - p = rffi.cast(llmemory.Address, p) + p = rffi.cast(llmemory.Address, p) TVAL = lltype.typeOf(newvalue) p = rffi.cast(rffi.CArrayPtr(TVAL), p + ofs) p[0] = newvalue @@ -691,9 +689,7 @@ def op_raw_load(TVAL, p, ofs): from rpython.rtyper.lltypesystem import rffi TP = lltype.typeOf(p) - if TP != llmemory.Address: - assert TP == llmemory.GCREF - p = rffi.cast(llmemory.Address, p) + p = rffi.cast(llmemory.Address, p) p = rffi.cast(rffi.CArrayPtr(TVAL), p + ofs) return p[0] op_raw_load.need_result_type = True From noreply at buildbot.pypy.org Mon Sep 9 19:16:49 2013 From: noreply at buildbot.pypy.org (arigo) Date: Mon, 9 Sep 2013 19:16:49 +0200 (CEST) Subject: [pypy-commit] pypy default: Kill unused lines Message-ID: <20130909171649.CAB151C02A7@cobra.cs.uni-duesseldorf.de> Author: Armin Rigo Branch: Changeset: r66872:74bd88216584 Date: 2013-09-09 19:15 +0200 http://bitbucket.org/pypy/pypy/changeset/74bd88216584/ Log: Kill unused lines 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 @@ -662,7 +662,6 @@ def op_raw_store(p, ofs, newvalue): from rpython.rtyper.lltypesystem import rffi - TP = lltype.typeOf(p) p = rffi.cast(llmemory.Address, p) TVAL = lltype.typeOf(newvalue) p = rffi.cast(rffi.CArrayPtr(TVAL), p + ofs) @@ -670,7 +669,6 @@ def op_raw_load(TVAL, p, ofs): from rpython.rtyper.lltypesystem import rffi - TP = lltype.typeOf(p) p = rffi.cast(llmemory.Address, p) p = rffi.cast(rffi.CArrayPtr(TVAL), p + ofs) return p[0] From noreply at buildbot.pypy.org Mon Sep 9 20:13:34 2013 From: noreply at buildbot.pypy.org (arigo) Date: Mon, 9 Sep 2013 20:13:34 +0200 (CEST) Subject: [pypy-commit] pypy default: Ignore this branch merge Message-ID: <20130909181334.A3F8B1C026D@cobra.cs.uni-duesseldorf.de> Author: Armin Rigo Branch: Changeset: r66873:5597c038128c Date: 2013-09-09 20:12 +0200 http://bitbucket.org/pypy/pypy/changeset/5597c038128c/ Log: Ignore this branch merge 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 @@ -80,6 +80,7 @@ .. branch: reflex-support .. branch: numpypy-inplace-op .. branch: rewritten-loop-logging +.. branch: no-release-gil .. branch: nobold-backtrace Work on improving UnionError messages and stack trace displays. From noreply at buildbot.pypy.org Mon Sep 9 21:24:36 2013 From: noreply at buildbot.pypy.org (mattip) Date: Mon, 9 Sep 2013 21:24:36 +0200 (CEST) Subject: [pypy-commit] pypy pypy-pyarray: revert to original c-macro (segfaulting) style api for consistency with numpy Message-ID: <20130909192436.1C4FC1C02A7@cobra.cs.uni-duesseldorf.de> Author: Matti Picus Branch: pypy-pyarray Changeset: r66874:02814fa15f6c Date: 2013-09-09 22:19 +0300 http://bitbucket.org/pypy/pypy/changeset/02814fa15f6c/ Log: revert to original c-macro (segfaulting) style api for consistency with numpy diff --git a/pypy/module/cpyext/ndarrayobject.py b/pypy/module/cpyext/ndarrayobject.py --- a/pypy/module/cpyext/ndarrayobject.py +++ b/pypy/module/cpyext/ndarrayobject.py @@ -5,7 +5,7 @@ from pypy.interpreter.error import OperationError from rpython.rtyper.lltypesystem import rffi -from pypy.module.cpyext.api import cpython_api, Py_ssize_t, CANNOT_FAIL, _NOT_SPECIFIED +from pypy.module.cpyext.api import cpython_api, Py_ssize_t, CANNOT_FAIL from pypy.module.cpyext.pyobject import PyObject from pypy.module.micronumpy.interp_numarray import W_NDimArray, convert_to_array, wrap_impl from pypy.module.micronumpy.interp_dtype import get_dtype_cache @@ -57,11 +57,9 @@ w_type = space.gettypeobject(W_NDimArray.typedef) return space.is_w(w_obj_type, w_type) - at cpython_api([PyObject], rffi.INT_real, error=-1) + at cpython_api([PyObject], rffi.INT_real, error=CANNOT_FAIL) def _PyArray_FLAGS(space, w_array): - if not isinstance(w_array, W_NDimArray): - raise OperationError(space.w_TypeError, space.wrap( - '_PyArray_FLAGS(ndarray) called with non-ndarray')) + assert isinstance(w_array, W_NDimArray) flags = NPY_BEHAVED_NS if isinstance(w_array.implementation, ConcreteArray): flags |= NPY_OWNDATA @@ -73,67 +71,51 @@ flags |= NPY_F_CONTIGUOUS return flags - at cpython_api([PyObject], rffi.INT_real, error=-1) + at cpython_api([PyObject], rffi.INT_real, error=CANNOT_FAIL) def _PyArray_NDIM(space, w_array): - if not isinstance(w_array, W_NDimArray): - raise OperationError(space.w_TypeError, space.wrap( - '_PyArray_NDIM(ndarray) called with non-ndarray')) + assert isinstance(w_array, W_NDimArray) return len(w_array.get_shape()) - at cpython_api([PyObject, Py_ssize_t], Py_ssize_t, error=-1) + at cpython_api([PyObject, Py_ssize_t], Py_ssize_t, error=CANNOT_FAIL) def _PyArray_DIM(space, w_array, n): - if not isinstance(w_array, W_NDimArray): - raise OperationError(space.w_TypeError, space.wrap( - '_PyArray_DIM called with non-ndarray')) + assert isinstance(w_array, W_NDimArray) return w_array.get_shape()[n] - at cpython_api([PyObject, Py_ssize_t], Py_ssize_t, error=-1) + at cpython_api([PyObject, Py_ssize_t], Py_ssize_t, error=CANNOT_FAIL) def _PyArray_STRIDE(space, w_array, n): - if not isinstance(w_array, W_NDimArray): - raise OperationError(space.w_TypeError, space.wrap( - '_PyArray_STRIDE called with non-ndarray')) + assert isinstance(w_array, W_NDimArray) return w_array.implementation.get_strides()[n] - at cpython_api([PyObject], Py_ssize_t, error=-1) + at cpython_api([PyObject], Py_ssize_t, error=CANNOT_FAIL) def _PyArray_SIZE(space, w_array): - if not isinstance(w_array, W_NDimArray): - raise OperationError(space.w_TypeError, space.wrap( - '_PyArray_SIZE called with non-ndarray')) + assert isinstance(w_array, W_NDimArray) return w_array.get_size() - at cpython_api([PyObject], rffi.INT_real, error=-1) + at cpython_api([PyObject], rffi.INT_real, error=CANNOT_FAIL) def _PyArray_ITEMSIZE(space, w_array): - if not isinstance(w_array, W_NDimArray): - raise OperationError(space.w_TypeError, space.wrap( - '_PyArray_ITEMSIZE called with non-ndarray')) + assert isinstance(w_array, W_NDimArray) return w_array.get_dtype().get_size() - at cpython_api([PyObject], Py_ssize_t, error=-1) + at cpython_api([PyObject], Py_ssize_t, error=CANNOT_FAIL) def _PyArray_NBYTES(space, w_array): - if not isinstance(w_array, W_NDimArray): - raise OperationError(space.w_TypeError, space.wrap( - '_PyArray_NBYTES called with non-ndarray')) + assert isinstance(w_array, W_NDimArray) return w_array.get_size() * w_array.get_dtype().get_size() - at cpython_api([PyObject], rffi.INT_real, error=-1) + at cpython_api([PyObject], rffi.INT_real, error=CANNOT_FAIL) def _PyArray_TYPE(space, w_array): - if not isinstance(w_array, W_NDimArray): - raise OperationError(space.w_TypeError, space.wrap( - '_PyArray_TYPE called with non-ndarray')) + assert isinstance(w_array, W_NDimArray) return w_array.get_dtype().num - at cpython_api([PyObject], rffi.VOIDP, error=_NOT_SPECIFIED) + at cpython_api([PyObject], rffi.VOIDP, error=CANNOT_FAIL) def _PyArray_DATA(space, w_array): # fails on scalars - see PyArray_FromAny() - if not isinstance(w_array, W_NDimArray): - raise OperationError(space.w_TypeError, space.wrap( - '_PyArray_DATA called with non-ndarray')) + assert isinstance(w_array, W_NDimArray) return rffi.cast(rffi.VOIDP, w_array.implementation.storage) @cpython_api([PyObject, rffi.VOIDP, Py_ssize_t, Py_ssize_t, Py_ssize_t, rffi.VOIDP], - PyObject, error=CANNOT_FAIL) + PyObject) def _PyArray_FromAny(space, w_obj, dtype, min_depth, max_depth, requirements, context): """ This is the main function used to obtain an array from any nested sequence, or object that exposes the array interface, op. The diff --git a/pypy/module/cpyext/test/test_ndarrayobject.py b/pypy/module/cpyext/test/test_ndarrayobject.py --- a/pypy/module/cpyext/test/test_ndarrayobject.py +++ b/pypy/module/cpyext/test/test_ndarrayobject.py @@ -62,7 +62,6 @@ def test_NBYTES(self, space, api): a = array(space, [10, 5, 3]) assert api._PyArray_NBYTES(a) == 1200 - self.raises(space, api, TypeError, api._PyArray_NBYTES, space.wrap([10])) def test_TYPE(self, space, api): a = array(space, [10, 5, 3]) From noreply at buildbot.pypy.org Mon Sep 9 21:26:34 2013 From: noreply at buildbot.pypy.org (pjenvey) Date: Mon, 9 Sep 2013 21:26:34 +0200 (CEST) Subject: [pypy-commit] pypy py3k: copy over from the pypy3-release-2.1.x branch Message-ID: <20130909192634.4546F1C02A7@cobra.cs.uni-duesseldorf.de> Author: Philip Jenvey Branch: py3k Changeset: r66875:7f9bcea88ed3 Date: 2013-09-09 12:25 -0700 http://bitbucket.org/pypy/pypy/changeset/7f9bcea88ed3/ Log: copy over from the pypy3-release-2.1.x branch diff --git a/pypy/doc/release-pypy3-2.1.0-beta1.rst b/pypy/doc/release-pypy3-2.1.0-beta1.rst new file mode 100644 --- /dev/null +++ b/pypy/doc/release-pypy3-2.1.0-beta1.rst @@ -0,0 +1,56 @@ +================ +PyPy3 2.1 beta 1 +================ + +We're pleased to announce the first beta of the upcoming 2.1 release of +PyPy3. This is the first release of PyPy which targets Python 3 (3.2.3) +compatibility. + +We would like to thank all of the people who donated_ to the `py3k proposal`_ +for supporting the work that went into this and future releases. + +You can download the PyPy3 2.1 beta 1 release here: + + http://pypy.org/download.html#pypy3-2-1-beta-1 + +Highlights +========== + +* The first release of PyPy3: support for Python 3, targetting CPython 3.2.3! + + - There are some `known issues`_ including performance regressions (issues + `#1540`_ & `#1541`_) slated to be resolved before the final release. + +What is PyPy? +============== + +PyPy is a very compliant Python interpreter, almost a drop-in replacement for +CPython 2.7.3 or 3.2.3. It's fast due to its integrated tracing JIT compiler. + +This release supports x86 machines running Linux 32/64, Mac OS X 64 or Windows +32. Also this release supports ARM machines running Linux 32bit - anything with +``ARMv6`` (like the Raspberry Pi) or ``ARMv7`` (like Beagleboard, +Chromebook, Cubieboard, etc.) that supports ``VFPv3`` should work. + +Windows 64 work is still stalling and we would welcome a volunteer to handle +that. + +How to use PyPy? +================= + +We suggest using PyPy from a `virtualenv`_. Once you have a virtualenv +installed, you can follow instructions from `pypy documentation`_ on how +to proceed. This document also covers other `installation schemes`_. + +.. _donated: http://morepypy.blogspot.com/2012/01/py3k-and-numpy-first-stage-thanks-to.html +.. _`py3k proposal`: http://pypy.org/py3donate.html +.. _`known issues`: https://bugs.pypy.org/issue?%40search_text=&title=py3k&%40columns=title&keyword=&id=&%40columns=id&creation=&creator=&release=&activity=&%40columns=activity&%40sort=activity&actor=&priority=&%40group=priority&status=-1%2C1%2C2%2C3%2C4%2C5%2C6&%40columns=status&assignedto=&%40columns=assignedto&%40pagesize=50&%40startwith=0&%40queryname=&%40old-queryname=&%40action=search +.. _`#1540`: https://bugs.pypy.org/issue1540 +.. _`#1541`: https://bugs.pypy.org/issue1541 +.. _`pypy documentation`: http://doc.pypy.org/en/latest/getting-started.html#installing-using-virtualenv +.. _`virtualenv`: http://www.virtualenv.org/en/latest/ +.. _`installation schemes`: http://doc.pypy.org/en/latest/getting-started.html#installing-pypy + + +Cheers, +the PyPy team diff --git a/pypy/doc/whatsnew-pypy3-2.1.0-beta1.rst b/pypy/doc/whatsnew-pypy3-2.1.0-beta1.rst new file mode 100644 --- /dev/null +++ b/pypy/doc/whatsnew-pypy3-2.1.0-beta1.rst @@ -0,0 +1,6 @@ +========================= +What's new in PyPy3 2.1.0 +========================= + +.. this is a revision shortly after pypy3-release-2.1.x +.. startrev: 1fc106b34e94 From noreply at buildbot.pypy.org Mon Sep 9 21:57:28 2013 From: noreply at buildbot.pypy.org (arigo) Date: Mon, 9 Sep 2013 21:57:28 +0200 (CEST) Subject: [pypy-commit] pypy default: Test and fix. Message-ID: <20130909195728.0F4201C12DA@cobra.cs.uni-duesseldorf.de> Author: Armin Rigo Branch: Changeset: r66876:0e2f0d910e8f Date: 2013-09-09 21:55 +0200 http://bitbucket.org/pypy/pypy/changeset/0e2f0d910e8f/ Log: Test and fix. diff --git a/rpython/rtyper/rpbc.py b/rpython/rtyper/rpbc.py --- a/rpython/rtyper/rpbc.py +++ b/rpython/rtyper/rpbc.py @@ -596,6 +596,9 @@ def ll_str(self, none): return llstr("None") + def get_ll_eq_function(self): + return None + def get_ll_hash_function(self): return ll_none_hash diff --git a/rpython/rtyper/test/test_rdict.py b/rpython/rtyper/test/test_rdict.py --- a/rpython/rtyper/test/test_rdict.py +++ b/rpython/rtyper/test/test_rdict.py @@ -1051,6 +1051,13 @@ finally: lltype._array._check_range = original_check_range + def test_dict_with_none_key(self): + def func(i): + d = {None: i} + return d[None] + res = self.interpret(func, [42]) + assert res == 42 + class TestStress: From noreply at buildbot.pypy.org Mon Sep 9 22:07:51 2013 From: noreply at buildbot.pypy.org (arigo) Date: Mon, 9 Sep 2013 22:07:51 +0200 (CEST) Subject: [pypy-commit] pypy default: We don't need do_write_barrier() any more. Message-ID: <20130909200751.A17CF1C12DA@cobra.cs.uni-duesseldorf.de> Author: Armin Rigo Branch: Changeset: r66877:abb1e075eae6 Date: 2013-09-09 21:14 +0200 http://bitbucket.org/pypy/pypy/changeset/abb1e075eae6/ Log: We don't need do_write_barrier() any more. 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 @@ -64,8 +64,6 @@ return True def initialize(self): pass - def do_write_barrier(self, gcref_struct, gcref_newptr): - pass def can_use_nursery_malloc(self, size): return False def has_write_barrier_class(self): @@ -547,17 +545,6 @@ hdr = llmemory.cast_adr_to_ptr(hdr_addr, self.HDRPTR) hdr.tid = tid - def do_write_barrier(self, gcref_struct, gcref_newptr): - hdr_addr = llmemory.cast_ptr_to_adr(gcref_struct) - hdr_addr -= self.gcheaderbuilder.size_gc_header - hdr = llmemory.cast_adr_to_ptr(hdr_addr, self.HDRPTR) - if hdr.tid & self.GCClass.JIT_WB_IF_FLAG: - # get a pointer to the 'remember_young_pointer' function from - # the GC, and call it immediately - llop1 = self.llop1 - funcptr = llop1.get_write_barrier_failing_case(self.WB_FUNCPTR) - funcptr(llmemory.cast_ptr_to_adr(gcref_struct)) - def can_use_nursery_malloc(self, size): return size < self.max_size_of_young_obj 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 @@ -175,26 +175,6 @@ repr(basesize), repr(itemsize), repr(ofs_length), p)] - def test_do_write_barrier(self): - gc_ll_descr = self.gc_ll_descr - R = lltype.GcStruct('R') - S = lltype.GcStruct('S', ('r', lltype.Ptr(R))) - s = lltype.malloc(S) - r = lltype.malloc(R) - s_hdr = gc_ll_descr.gcheaderbuilder.new_header(s) - s_gcref = lltype.cast_opaque_ptr(llmemory.GCREF, s) - r_gcref = lltype.cast_opaque_ptr(llmemory.GCREF, r) - s_adr = llmemory.cast_ptr_to_adr(s) - llmemory.cast_ptr_to_adr(r) - # - s_hdr.tid &= ~gc_ll_descr.GCClass.JIT_WB_IF_FLAG - gc_ll_descr.do_write_barrier(s_gcref, r_gcref) - assert self.llop1.record == [] # not called - # - s_hdr.tid |= gc_ll_descr.GCClass.JIT_WB_IF_FLAG - gc_ll_descr.do_write_barrier(s_gcref, r_gcref) - assert self.llop1.record == [('barrier', s_adr)] - def test_gen_write_barrier(self): gc_ll_descr = self.gc_ll_descr llop1 = self.llop1 From noreply at buildbot.pypy.org Mon Sep 9 22:07:52 2013 From: noreply at buildbot.pypy.org (arigo) Date: Mon, 9 Sep 2013 22:07:52 +0200 (CEST) Subject: [pypy-commit] pypy default: Oups, attempt to fix translation Message-ID: <20130909200752.DA06C1C12DA@cobra.cs.uni-duesseldorf.de> Author: Armin Rigo Branch: Changeset: r66878:2df4a2cdc3d4 Date: 2013-09-09 21:19 +0200 http://bitbucket.org/pypy/pypy/changeset/2df4a2cdc3d4/ Log: Oups, attempt to fix translation 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 @@ -418,7 +418,6 @@ bh_setfield_raw = bh_setfield_gc bh_setfield_raw_i = bh_setfield_raw - bh_setfield_raw_r = bh_setfield_raw bh_setfield_raw_f = bh_setfield_raw def bh_arraylen_gc(self, a, descr): 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 @@ -390,9 +390,11 @@ else: raise NotImplementedError("size = %d" % size) + @specialize.argtype(1) def read_ref_at_mem(self, gcref, ofs): return llop.raw_load(llmemory.GCREF, gcref, ofs) + # non- at specialized: must only be called with llmemory.GCREF def write_ref_at_mem(self, gcref, ofs, newvalue): llop.raw_store(lltype.Void, gcref, ofs, newvalue) # the write barrier is implied above @@ -541,6 +543,7 @@ ofs, size, sign = self.unpack_fielddescr_size(fielddescr) return self.read_int_at_mem(struct, ofs, size, sign) + @specialize.argtype(1) def bh_getfield_gc_r(self, struct, fielddescr): ofs = self.unpack_fielddescr(fielddescr) return self.read_ref_at_mem(struct, ofs) @@ -551,6 +554,7 @@ return self.read_float_at_mem(struct, ofs) bh_getfield_raw_i = bh_getfield_gc_i + bh_getfield_raw_r = bh_getfield_gc_r bh_getfield_raw_f = bh_getfield_gc_f @specialize.argtype(1) 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 @@ -264,8 +264,6 @@ def bh_setfield_raw_i(self, struct, newvalue, fielddescr): raise NotImplementedError - def bh_setfield_raw_r(self, struct, newvalue, fielddescr): - raise NotImplementedError def bh_setfield_raw_f(self, struct, newvalue, fielddescr): raise NotImplementedError 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 @@ -688,6 +688,10 @@ kind = getkind(RESULT)[0] op1 = SpaceOperation('getfield_%s_%s%s' % (argname, kind, pure), [v_inst, descr], op.result) + if op1.opname == 'getfield_raw_r': + # note: 'getfield_raw_r_pure' is used e.g. to load class + # attributes that are GC objects, so that one is supported. + raise Exception("getfield_raw_r (without _pure) not supported") # if immut in (IR_QUASIIMMUTABLE, IR_QUASIIMMUTABLE_ARRAY): descr1 = self.cpu.fielddescrof( @@ -720,6 +724,8 @@ descr = self.cpu.fielddescrof(v_inst.concretetype.TO, c_fieldname.value) kind = getkind(RESULT)[0] + if argname == 'raw' and kind == 'r': + raise Exception("setfield_raw_r not supported") return SpaceOperation('setfield_%s_%s' % (argname, kind), [v_inst, v_value, descr], None) 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 @@ -1263,14 +1263,15 @@ def bhimpl_getfield_raw_i(cpu, struct, fielddescr): return cpu.bh_getfield_raw_i(struct, fielddescr) @arguments("cpu", "i", "d", returns="r") - def bhimpl_getfield_raw_r(cpu, struct, fielddescr): + def _bhimpl_getfield_raw_r(cpu, struct, fielddescr): + # only for 'getfield_raw_r_pure' return cpu.bh_getfield_raw_r(struct, fielddescr) @arguments("cpu", "i", "d", returns="f") def bhimpl_getfield_raw_f(cpu, struct, fielddescr): return cpu.bh_getfield_raw_f(struct, fielddescr) bhimpl_getfield_raw_i_pure = bhimpl_getfield_raw_i - bhimpl_getfield_raw_r_pure = bhimpl_getfield_raw_r + bhimpl_getfield_raw_r_pure = _bhimpl_getfield_raw_r bhimpl_getfield_raw_f_pure = bhimpl_getfield_raw_f @arguments("cpu", "r", "i", "d") @@ -1290,9 +1291,6 @@ @arguments("cpu", "i", "i", "d") def bhimpl_setfield_raw_i(cpu, struct, newvalue, fielddescr): cpu.bh_setfield_raw_i(struct, newvalue, fielddescr) - @arguments("cpu", "i", "r", "d") - def bhimpl_setfield_raw_r(cpu, struct, newvalue, fielddescr): - cpu.bh_setfield_raw_r(struct, newvalue, fielddescr) @arguments("cpu", "i", "f", "d") def bhimpl_setfield_raw_f(cpu, struct, newvalue, fielddescr): cpu.bh_setfield_raw_f(struct, newvalue, fielddescr) 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 @@ -177,9 +177,8 @@ def do_setfield_raw(cpu, _, structbox, itembox, fielddescr): struct = structbox.getint() - if fielddescr.is_pointer_field(): - cpu.bh_setfield_raw_r(struct, itembox.getref_base(), fielddescr) - elif fielddescr.is_float_field(): + assert not fielddescr.is_pointer_field() + if fielddescr.is_float_field(): cpu.bh_setfield_raw_f(struct, itembox.getfloatstorage(), fielddescr) else: cpu.bh_setfield_raw_i(struct, itembox.getint(), fielddescr) 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 @@ -643,7 +643,6 @@ def _opimpl_getfield_raw_any(self, box, fielddescr): return self.execute_with_descr(rop.GETFIELD_RAW, fielddescr, box) opimpl_getfield_raw_i = _opimpl_getfield_raw_any - opimpl_getfield_raw_r = _opimpl_getfield_raw_any opimpl_getfield_raw_f = _opimpl_getfield_raw_any @arguments("box", "descr") @@ -657,7 +656,6 @@ def _opimpl_setfield_raw_any(self, box, valuebox, fielddescr): self.execute_with_descr(rop.SETFIELD_RAW, fielddescr, box, valuebox) opimpl_setfield_raw_i = _opimpl_setfield_raw_any - opimpl_setfield_raw_r = _opimpl_setfield_raw_any opimpl_setfield_raw_f = _opimpl_setfield_raw_any @arguments("box", "box", "box", "descr") From noreply at buildbot.pypy.org Mon Sep 9 22:07:54 2013 From: noreply at buildbot.pypy.org (arigo) Date: Mon, 9 Sep 2013 22:07:54 +0200 (CEST) Subject: [pypy-commit] pypy default: Move gc_writebarrier() closer to where it needs to be: just before calling the assembler Message-ID: <20130909200754.013241C12DA@cobra.cs.uni-duesseldorf.de> Author: Armin Rigo Branch: Changeset: r66879:f21ab1e8ae20 Date: 2013-09-09 22:01 +0200 http://bitbucket.org/pypy/pypy/changeset/f21ab1e8ae20/ Log: Move gc_writebarrier() closer to where it needs to be: just before calling the assembler 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 @@ -133,9 +133,7 @@ def malloc_jitframe(self, frame_info): """ Allocate a new frame, overwritten by tests """ - frame = jitframe.JITFRAME.allocate(frame_info) - llop.gc_writebarrier(lltype.Void, frame) - return frame + return jitframe.JITFRAME.allocate(frame_info) class JitFrameDescrs: def _freeze_(self): 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 @@ -247,6 +247,7 @@ else: assert kind == history.REF self.set_ref_value(ll_frame, num, arg) + llop.gc_writebarrier(lltype.Void, ll_frame) ll_frame = func(ll_frame) finally: if not self.translate_support_code: From noreply at buildbot.pypy.org Mon Sep 9 22:07:55 2013 From: noreply at buildbot.pypy.org (arigo) Date: Mon, 9 Sep 2013 22:07:55 +0200 (CEST) Subject: [pypy-commit] pypy default: merge heads Message-ID: <20130909200755.195F91C12DA@cobra.cs.uni-duesseldorf.de> Author: Armin Rigo Branch: Changeset: r66880:619ceb5c24c8 Date: 2013-09-09 22:07 +0200 http://bitbucket.org/pypy/pypy/changeset/619ceb5c24c8/ Log: merge heads diff --git a/rpython/rtyper/rpbc.py b/rpython/rtyper/rpbc.py --- a/rpython/rtyper/rpbc.py +++ b/rpython/rtyper/rpbc.py @@ -596,6 +596,9 @@ def ll_str(self, none): return llstr("None") + def get_ll_eq_function(self): + return None + def get_ll_hash_function(self): return ll_none_hash diff --git a/rpython/rtyper/test/test_rdict.py b/rpython/rtyper/test/test_rdict.py --- a/rpython/rtyper/test/test_rdict.py +++ b/rpython/rtyper/test/test_rdict.py @@ -1051,6 +1051,13 @@ finally: lltype._array._check_range = original_check_range + def test_dict_with_none_key(self): + def func(i): + d = {None: i} + return d[None] + res = self.interpret(func, [42]) + assert res == 42 + class TestStress: From noreply at buildbot.pypy.org Mon Sep 9 22:18:20 2013 From: noreply at buildbot.pypy.org (arigo) Date: Mon, 9 Sep 2013 22:18:20 +0200 (CEST) Subject: [pypy-commit] pypy stmgc-c4: hg merge default Message-ID: <20130909201820.D148D1C026D@cobra.cs.uni-duesseldorf.de> Author: Armin Rigo Branch: stmgc-c4 Changeset: r66881:6bcc88ab4f2b Date: 2013-09-09 22:17 +0200 http://bitbucket.org/pypy/pypy/changeset/6bcc88ab4f2b/ Log: hg 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 @@ -80,6 +80,7 @@ .. branch: reflex-support .. branch: numpypy-inplace-op .. branch: rewritten-loop-logging +.. branch: no-release-gil .. branch: nobold-backtrace Work on improving UnionError messages and stack trace displays. 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 @@ -418,7 +418,6 @@ bh_setfield_raw = bh_setfield_gc bh_setfield_raw_i = bh_setfield_raw - bh_setfield_raw_r = bh_setfield_raw bh_setfield_raw_f = bh_setfield_raw def bh_arraylen_gc(self, a, descr): 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 @@ -65,11 +65,6 @@ return True def initialize(self): pass - @specialize.argtype(1) - def do_stm_barrier(self, gcref, cat): - return gcref - def do_write_barrier(self, gcref_struct, gcref_newptr): - pass def can_use_nursery_malloc(self, size): return False def has_write_barrier_class(self): @@ -150,9 +145,7 @@ def malloc_jitframe(self, frame_info): """ Allocate a new frame, overwritten by tests """ - frame = jitframe.JITFRAME.allocate(frame_info) - llop.gc_writebarrier(lltype.Void, frame) - return frame + return jitframe.JITFRAME.allocate(frame_info) class JitFrameDescrs: def _freeze_(self): @@ -585,30 +578,11 @@ def _setup_write_barrier(self): if self.stm: - self._setup_barriers_for_stm() + self.P2Rdescr = STMReadBarrierDescr(self, 'P2R') + self.P2Wdescr = STMWriteBarrierDescr(self, 'P2W') + self.write_barrier_descr = "wbdescr: do not use" else: self.write_barrier_descr = WriteBarrierDescr(self) - def do_write_barrier(gcref_struct, gcref_newptr): - self.write_barrier_descr._do_barrier(gcref_struct, False) - self.do_write_barrier = do_write_barrier - - def _setup_barriers_for_stm(self): - self.P2Rdescr = STMReadBarrierDescr(self, 'P2R') - self.P2Wdescr = STMWriteBarrierDescr(self, 'P2W') - self.write_barrier_descr = "wbdescr: do not use" - # - @specialize.argtype(0) - def do_stm_barrier(gcref, cat): - if lltype.typeOf(gcref) is lltype.Signed: # ignore if 'raw' - # we are inevitable already because llmodel - # does everything with raw-references - return gcref - if cat == 'W': - descr = self.P2Wdescr - else: - descr = self.P2Rdescr - return descr._do_barrier(gcref, True) - self.do_stm_barrier = do_stm_barrier def _make_functions(self, really_not_translated): from rpython.memory.gctypelayout import check_typeid 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 @@ -252,6 +252,7 @@ else: assert kind == history.REF self.set_ref_value(ll_frame, num, arg) + llop.gc_writebarrier(lltype.Void, ll_frame) # This is the line that calls the assembler code. # 'func(ll_frame)' would work here too, producing an # indirect_call(func, ll_frame, None). The main difference @@ -401,9 +402,11 @@ else: raise NotImplementedError("size = %d" % size) + @specialize.argtype(1) def read_ref_at_mem(self, gcref, ofs): return llop.raw_load(llmemory.GCREF, gcref, ofs) + # non- at specialized: must only be called with llmemory.GCREF def write_ref_at_mem(self, gcref, ofs, newvalue): llop.raw_store(lltype.Void, gcref, ofs, newvalue) # the write barrier is implied above @@ -552,6 +555,7 @@ ofs, size, sign = self.unpack_fielddescr_size(fielddescr) return self.read_int_at_mem(struct, ofs, size, sign) + @specialize.argtype(1) def bh_getfield_gc_r(self, struct, fielddescr): ofs = self.unpack_fielddescr(fielddescr) return self.read_ref_at_mem(struct, ofs) @@ -562,6 +566,7 @@ return self.read_float_at_mem(struct, ofs) bh_getfield_raw_i = bh_getfield_gc_i + bh_getfield_raw_r = bh_getfield_gc_r bh_getfield_raw_f = bh_getfield_gc_f @specialize.argtype(1) 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 @@ -176,26 +176,6 @@ repr(basesize), repr(itemsize), repr(ofs_length), p)] - def test_do_write_barrier(self): - gc_ll_descr = self.gc_ll_descr - R = lltype.GcStruct('R') - S = lltype.GcStruct('S', ('r', lltype.Ptr(R))) - s = lltype.malloc(S) - r = lltype.malloc(R) - s_hdr = gc_ll_descr.gcheaderbuilder.new_header(s) - s_gcref = lltype.cast_opaque_ptr(llmemory.GCREF, s) - r_gcref = lltype.cast_opaque_ptr(llmemory.GCREF, r) - s_adr = llmemory.cast_ptr_to_adr(s) - llmemory.cast_ptr_to_adr(r) - # - s_hdr.tid &= ~gc_ll_descr.GCClass.JIT_WB_IF_FLAG - gc_ll_descr.do_write_barrier(s_gcref, r_gcref) - assert self.llop1.record == [] # not called - # - s_hdr.tid |= gc_ll_descr.GCClass.JIT_WB_IF_FLAG - gc_ll_descr.do_write_barrier(s_gcref, r_gcref) - assert self.llop1.record == [('barrier', s_adr)] - def test_gen_write_barrier(self): from rpython.jit.backend.llsupport.rewrite import GcRewriterAssembler gc_ll_descr = self.gc_ll_descr 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 @@ -264,8 +264,6 @@ def bh_setfield_raw_i(self, struct, newvalue, fielddescr): raise NotImplementedError - def bh_setfield_raw_r(self, struct, newvalue, fielddescr): - raise NotImplementedError def bh_setfield_raw_f(self, struct, newvalue, fielddescr): raise NotImplementedError 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 @@ -688,6 +688,10 @@ kind = getkind(RESULT)[0] op1 = SpaceOperation('getfield_%s_%s%s' % (argname, kind, pure), [v_inst, descr], op.result) + if op1.opname == 'getfield_raw_r': + # note: 'getfield_raw_r_pure' is used e.g. to load class + # attributes that are GC objects, so that one is supported. + raise Exception("getfield_raw_r (without _pure) not supported") # if immut in (IR_QUASIIMMUTABLE, IR_QUASIIMMUTABLE_ARRAY): descr1 = self.cpu.fielddescrof( @@ -720,6 +724,8 @@ descr = self.cpu.fielddescrof(v_inst.concretetype.TO, c_fieldname.value) kind = getkind(RESULT)[0] + if argname == 'raw' and kind == 'r': + raise Exception("setfield_raw_r not supported") return SpaceOperation('setfield_%s_%s' % (argname, kind), [v_inst, v_value, descr], None) 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 @@ -1263,14 +1263,15 @@ def bhimpl_getfield_raw_i(cpu, struct, fielddescr): return cpu.bh_getfield_raw_i(struct, fielddescr) @arguments("cpu", "i", "d", returns="r") - def bhimpl_getfield_raw_r(cpu, struct, fielddescr): + def _bhimpl_getfield_raw_r(cpu, struct, fielddescr): + # only for 'getfield_raw_r_pure' return cpu.bh_getfield_raw_r(struct, fielddescr) @arguments("cpu", "i", "d", returns="f") def bhimpl_getfield_raw_f(cpu, struct, fielddescr): return cpu.bh_getfield_raw_f(struct, fielddescr) bhimpl_getfield_raw_i_pure = bhimpl_getfield_raw_i - bhimpl_getfield_raw_r_pure = bhimpl_getfield_raw_r + bhimpl_getfield_raw_r_pure = _bhimpl_getfield_raw_r bhimpl_getfield_raw_f_pure = bhimpl_getfield_raw_f @arguments("cpu", "r", "i", "d") @@ -1290,9 +1291,6 @@ @arguments("cpu", "i", "i", "d") def bhimpl_setfield_raw_i(cpu, struct, newvalue, fielddescr): cpu.bh_setfield_raw_i(struct, newvalue, fielddescr) - @arguments("cpu", "i", "r", "d") - def bhimpl_setfield_raw_r(cpu, struct, newvalue, fielddescr): - cpu.bh_setfield_raw_r(struct, newvalue, fielddescr) @arguments("cpu", "i", "f", "d") def bhimpl_setfield_raw_f(cpu, struct, newvalue, fielddescr): cpu.bh_setfield_raw_f(struct, newvalue, fielddescr) 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 @@ -177,9 +177,8 @@ def do_setfield_raw(cpu, _, structbox, itembox, fielddescr): struct = structbox.getint() - if fielddescr.is_pointer_field(): - cpu.bh_setfield_raw_r(struct, itembox.getref_base(), fielddescr) - elif fielddescr.is_float_field(): + assert not fielddescr.is_pointer_field() + if fielddescr.is_float_field(): cpu.bh_setfield_raw_f(struct, itembox.getfloatstorage(), fielddescr) else: cpu.bh_setfield_raw_i(struct, itembox.getint(), fielddescr) 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 @@ -643,7 +643,6 @@ def _opimpl_getfield_raw_any(self, box, fielddescr): return self.execute_with_descr(rop.GETFIELD_RAW, fielddescr, box) opimpl_getfield_raw_i = _opimpl_getfield_raw_any - opimpl_getfield_raw_r = _opimpl_getfield_raw_any opimpl_getfield_raw_f = _opimpl_getfield_raw_any @arguments("box", "descr") @@ -657,7 +656,6 @@ def _opimpl_setfield_raw_any(self, box, valuebox, fielddescr): self.execute_with_descr(rop.SETFIELD_RAW, fielddescr, box, valuebox) opimpl_setfield_raw_i = _opimpl_setfield_raw_any - opimpl_setfield_raw_r = _opimpl_setfield_raw_any opimpl_setfield_raw_f = _opimpl_setfield_raw_any @arguments("box", "box", "box", "descr") 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 @@ -680,7 +680,6 @@ def op_raw_store(p, ofs, newvalue): from rpython.rtyper.lltypesystem import rffi - TP = lltype.typeOf(p) p = rffi.cast(llmemory.Address, p) TVAL = lltype.typeOf(newvalue) p = rffi.cast(rffi.CArrayPtr(TVAL), p + ofs) @@ -688,7 +687,6 @@ def op_raw_load(TVAL, p, ofs): from rpython.rtyper.lltypesystem import rffi - TP = lltype.typeOf(p) p = rffi.cast(llmemory.Address, p) p = rffi.cast(rffi.CArrayPtr(TVAL), p + ofs) return p[0] diff --git a/rpython/rtyper/rpbc.py b/rpython/rtyper/rpbc.py --- a/rpython/rtyper/rpbc.py +++ b/rpython/rtyper/rpbc.py @@ -596,6 +596,9 @@ def ll_str(self, none): return llstr("None") + def get_ll_eq_function(self): + return None + def get_ll_hash_function(self): return ll_none_hash diff --git a/rpython/rtyper/test/test_rdict.py b/rpython/rtyper/test/test_rdict.py --- a/rpython/rtyper/test/test_rdict.py +++ b/rpython/rtyper/test/test_rdict.py @@ -1051,6 +1051,13 @@ finally: lltype._array._check_range = original_check_range + def test_dict_with_none_key(self): + def func(i): + d = {None: i} + return d[None] + res = self.interpret(func, [42]) + assert res == 42 + class TestStress: From noreply at buildbot.pypy.org Mon Sep 9 22:30:30 2013 From: noreply at buildbot.pypy.org (arigo) Date: Mon, 9 Sep 2013 22:30:30 +0200 (CEST) Subject: [pypy-commit] pypy stmgc-c4: A test and small fixes for gc_writebarrier in stm. Message-ID: <20130909203030.9A1BC1C02A7@cobra.cs.uni-duesseldorf.de> Author: Armin Rigo Branch: stmgc-c4 Changeset: r66882:de0e05b91573 Date: 2013-09-09 22:29 +0200 http://bitbucket.org/pypy/pypy/changeset/de0e05b91573/ Log: A test and small fixes for gc_writebarrier in stm. 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 @@ -745,9 +745,7 @@ resultvar=op.result) def gct_gc_writebarrier(self, hop): - # this operation is removed by stm/writebarrier.py - assert not self.translator.config.translation.stm - if self.write_barrier_ptr is None: + if self.write_barrier_ptr is None: # incl. in case of stm return op = hop.spaceop v_addr = op.args[0] diff --git a/rpython/translator/stm/inevitable.py b/rpython/translator/stm/inevitable.py --- a/rpython/translator/stm/inevitable.py +++ b/rpython/translator/stm/inevitable.py @@ -18,7 +18,7 @@ 'weakref_create', 'weakref_deref', 'stm_threadlocalref_get', 'stm_threadlocalref_set', 'stm_threadlocalref_count', 'stm_threadlocalref_addr', - 'jit_assembler_call', + 'jit_assembler_call', 'gc_writebarrier', ]) ALWAYS_ALLOW_OPERATIONS |= set(lloperation.enum_tryfold_ops()) diff --git a/rpython/translator/stm/test/test_ztranslated.py b/rpython/translator/stm/test/test_ztranslated.py --- a/rpython/translator/stm/test/test_ztranslated.py +++ b/rpython/translator/stm/test/test_ztranslated.py @@ -358,3 +358,21 @@ match = re.search(r"(\d+) mallocs left", dataerr) assert match assert int(match.group(1)) < 20 + + def test_gc_writebarrier(self): + class X(object): + pass + prebuilt = X() + prebuilt.foo = 42 + + def main(argv): + llop.gc_writebarrier(lltype.Void, prebuilt) + debug_print(objectmodel.current_object_addr_as_int(prebuilt)) + prebuilt.foo = 43 + debug_print(objectmodel.current_object_addr_as_int(prebuilt)) + return 0 + + t, cbuilder = self.compile(main) + data, dataerr = cbuilder.cmdexec('', err=True) + lines = dataerr.split('\n') + assert lines[0] == lines[1] diff --git a/rpython/translator/stm/writebarrier.py b/rpython/translator/stm/writebarrier.py --- a/rpython/translator/stm/writebarrier.py +++ b/rpython/translator/stm/writebarrier.py @@ -201,8 +201,6 @@ newoperations.append(newop) ren.newvar = w ren.category = to - if op.opname == 'gc_writebarrier': - continue # remove after inserting 'stm_barrier' # newop = SpaceOperation(op.opname, [renamings_get(v) for v in op.args], From noreply at buildbot.pypy.org Mon Sep 9 22:37:47 2013 From: noreply at buildbot.pypy.org (arigo) Date: Mon, 9 Sep 2013 22:37:47 +0200 (CEST) Subject: [pypy-commit] pypy stmgc-c4: Waa, this made gcc produce a warning: "/*" within comment Message-ID: <20130909203747.E288E1C02A7@cobra.cs.uni-duesseldorf.de> Author: Armin Rigo Branch: stmgc-c4 Changeset: r66883:4fa82aceb43c Date: 2013-09-09 22:37 +0200 http://bitbucket.org/pypy/pypy/changeset/4fa82aceb43c/ Log: Waa, this made gcc produce a warning: "/*" within comment diff --git a/rpython/translator/c/src/mem.c b/rpython/translator/c/src/mem.c --- a/rpython/translator/c/src/mem.c +++ b/rpython/translator/c/src/mem.c @@ -14,7 +14,7 @@ # endif void _pypy_stm_free(void *ptr) { - /* This is called by src_stm/*.c when the transaction is aborted + /* This is called by src_stm/et.c when the transaction is aborted and the 'ptr' was malloced but not freed. We have first to unregister the object with a tentative pypy_debug_alloc_stop(), which ignores it if it was not actually registered. Then we From noreply at buildbot.pypy.org Tue Sep 10 00:30:35 2013 From: noreply at buildbot.pypy.org (pjenvey) Date: Tue, 10 Sep 2013 00:30:35 +0200 (CEST) Subject: [pypy-commit] pypy py3k: merge default Message-ID: <20130909223035.EEB271C1128@cobra.cs.uni-duesseldorf.de> Author: Philip Jenvey Branch: py3k Changeset: r66884:c1f9cb9361f6 Date: 2013-09-09 14:18 -0700 http://bitbucket.org/pypy/pypy/changeset/c1f9cb9361f6/ Log: merge default diff too long, truncating to 2000 out of 7230 lines diff --git a/lib-python/2.7/uuid.py b/lib-python/2.7/uuid.py --- a/lib-python/2.7/uuid.py +++ b/lib-python/2.7/uuid.py @@ -44,6 +44,8 @@ UUID('00010203-0405-0607-0809-0a0b0c0d0e0f') """ +import struct + __author__ = 'Ka-Ping Yee ' RESERVED_NCS, RFC_4122, RESERVED_MICROSOFT, RESERVED_FUTURE = [ @@ -125,25 +127,38 @@ overriding the given 'hex', 'bytes', 'bytes_le', 'fields', or 'int'. """ - if [hex, bytes, bytes_le, fields, int].count(None) != 4: - raise TypeError('need one of hex, bytes, bytes_le, fields, or int') if hex is not None: + if (bytes is not None or bytes_le is not None or fields is not None + or int is not None): + raise TypeError('if the hex argument is given, bytes, bytes_le, fields,' + ' and int need to be None') hex = hex.replace('urn:', '').replace('uuid:', '') hex = hex.strip('{}').replace('-', '') if len(hex) != 32: raise ValueError('badly formed hexadecimal UUID string') int = long(hex, 16) - if bytes_le is not None: + elif bytes_le is not None: + if bytes is not None or fields is not None or int is not None: + raise TypeError('if the bytes_le argument is given, bytes, fields,' + ' and int need to be None') if len(bytes_le) != 16: raise ValueError('bytes_le is not a 16-char string') bytes = (bytes_le[3] + bytes_le[2] + bytes_le[1] + bytes_le[0] + bytes_le[5] + bytes_le[4] + bytes_le[7] + bytes_le[6] + bytes_le[8:]) - if bytes is not None: + int = (struct.unpack('>Q', bytes[:8])[0] << 64 | + struct.unpack('>Q', bytes[8:])[0]) + elif bytes is not None: + if fields is not None or int is not None: + raise TypeError('if the bytes argument is given, fields' + ' and int need to be None') if len(bytes) != 16: raise ValueError('bytes is not a 16-char string') - int = long(('%02x'*16) % tuple(map(ord, bytes)), 16) - if fields is not None: + int = (struct.unpack('>Q', bytes[:8])[0] << 64 | + struct.unpack('>Q', bytes[8:])[0]) + elif fields is not None: + if int is not None: + raise TypeError('if the fields argument is given, int needs to be None') if len(fields) != 6: raise ValueError('fields is not a 6-tuple') (time_low, time_mid, time_hi_version, @@ -163,9 +178,12 @@ clock_seq = (clock_seq_hi_variant << 8L) | clock_seq_low int = ((time_low << 96L) | (time_mid << 80L) | (time_hi_version << 64L) | (clock_seq << 48L) | node) - if int is not None: + elif int is not None: if not 0 <= int < 1<<128L: raise ValueError('int is out of range (need a 128-bit value)') + else: + raise TypeError('one of hex, bytes, bytes_le, fields,' + ' or int need to be not None') if version is not None: if not 1 <= version <= 5: raise ValueError('illegal version number') @@ -175,7 +193,7 @@ # Set the version number. int &= ~(0xf000 << 64L) int |= version << 76L - self.__dict__['int'] = int + object.__setattr__(self, 'int', int) def __cmp__(self, other): if isinstance(other, UUID): diff --git a/lib_pypy/_curses.py b/lib_pypy/_curses.py --- a/lib_pypy/_curses.py +++ b/lib_pypy/_curses.py @@ -1,6 +1,9 @@ """Reimplementation of the standard extension module '_curses' using cffi.""" import sys +if sys.platform == 'win32': + #This module does not exist in windows + raise ImportError('No module named _curses') from functools import wraps from cffi import FFI diff --git a/lib_pypy/_sqlite3.py b/lib_pypy/_sqlite3.py --- a/lib_pypy/_sqlite3.py +++ b/lib_pypy/_sqlite3.py @@ -1241,7 +1241,10 @@ if cvt is not None: param = cvt(param) - param = adapt(param) + try: + param = adapt(param) + except: + pass # And use previous value if param is None: rc = _lib.sqlite3_bind_null(self._statement, idx) diff --git a/lib_pypy/_tkinter/__init__.py b/lib_pypy/_tkinter/__init__.py --- a/lib_pypy/_tkinter/__init__.py +++ b/lib_pypy/_tkinter/__init__.py @@ -22,6 +22,7 @@ READABLE = tklib.TCL_READABLE WRITABLE = tklib.TCL_WRITABLE EXCEPTION = tklib.TCL_EXCEPTION +DONT_WAIT = tklib.TCL_DONT_WAIT def create(screenName=None, baseName=None, className=None, interactive=False, wantobjects=False, wantTk=True, diff --git a/lib_pypy/_tkinter/app.py b/lib_pypy/_tkinter/app.py --- a/lib_pypy/_tkinter/app.py +++ b/lib_pypy/_tkinter/app.py @@ -4,7 +4,23 @@ from . import TclError from .tclobj import TclObject, FromObj, AsObj, TypeCache +import contextlib import sys +import threading +import time + + +class _DummyLock(object): + "A lock-like object that does not do anything" + def acquire(self): + pass + def release(self): + pass + def __enter__(self): + pass + def __exit__(self, *exc): + pass + def varname_converter(input): if isinstance(input, TclObject): @@ -37,18 +53,19 @@ def PythonCmd(clientData, interp, argc, argv): self = tkffi.from_handle(clientData) assert self.app.interp == interp - try: - args = [tkffi.string(arg).decode('utf-8') - for arg in argv[1:argc]] - result = self.func(*args) - obj = AsObj(result) - tklib.Tcl_SetObjResult(interp, obj) - except: - self.app.errorInCmd = True - self.app.exc_info = sys.exc_info() - return tklib.TCL_ERROR - else: - return tklib.TCL_OK + with self.app._tcl_lock_released(): + try: + args = [tkffi.string(arg).decode('utf-8') + for arg in argv[1:argc]] + result = self.func(*args) + obj = AsObj(result) + tklib.Tcl_SetObjResult(interp, obj) + except: + self.app.errorInCmd = True + self.app.exc_info = sys.exc_info() + return tklib.TCL_ERROR + else: + return tklib.TCL_OK @tkffi.callback("Tcl_CmdDeleteProc") def PythonCmdDelete(clientData): @@ -59,6 +76,8 @@ class TkApp(object): + _busywaitinterval = 0.02 # 20ms. + def __new__(cls, screenName, className, interactive, wantobjects, wantTk, sync, use): if not wantobjects: @@ -74,6 +93,12 @@ self.quitMainLoop = False self.errorInCmd = False + if not self.threaded: + # TCL is not thread-safe, calls needs to be serialized. + self._tcl_lock = threading.Lock() + else: + self._tcl_lock = _DummyLock() + self._typeCache = TypeCache() self._commands = {} @@ -136,6 +161,13 @@ if self.threaded and self.thread_id != tklib.Tcl_GetCurrentThread(): raise RuntimeError("Calling Tcl from different appartment") + @contextlib.contextmanager + def _tcl_lock_released(self): + "Context manager to temporarily release the tcl lock." + self._tcl_lock.release() + yield + self._tcl_lock.acquire() + def loadtk(self): # We want to guard against calling Tk_Init() multiple times err = tklib.Tcl_Eval(self.interp, b"info exists tk_version") @@ -162,22 +194,25 @@ flags=tklib.TCL_LEAVE_ERR_MSG if global_only: flags |= tklib.TCL_GLOBAL_ONLY - res = tklib.Tcl_GetVar2Ex(self.interp, name1, name2, flags) - if not res: - self.raiseTclError() - assert self._wantobjects - return FromObj(self, res) + with self._tcl_lock: + res = tklib.Tcl_GetVar2Ex(self.interp, name1, name2, flags) + if not res: + self.raiseTclError() + assert self._wantobjects + return FromObj(self, res) def _setvar(self, name1, value, global_only=False): name1 = varname_converter(name1) + # XXX Acquire tcl lock??? newval = AsObj(value) flags=tklib.TCL_LEAVE_ERR_MSG if global_only: flags |= tklib.TCL_GLOBAL_ONLY - res = tklib.Tcl_SetVar2Ex(self.interp, name1, tkffi.NULL, - newval, flags) - if not res: - self.raiseTclError() + with self._tcl_lock: + res = tklib.Tcl_SetVar2Ex(self.interp, name1, tkffi.NULL, + newval, flags) + if not res: + self.raiseTclError() def _unsetvar(self, name1, name2=None, global_only=False): name1 = varname_converter(name1) @@ -186,9 +221,10 @@ flags=tklib.TCL_LEAVE_ERR_MSG if global_only: flags |= tklib.TCL_GLOBAL_ONLY - res = tklib.Tcl_UnsetVar2(self.interp, name1, name2, flags) - if res == tklib.TCL_ERROR: - self.raiseTclError() + with self._tcl_lock: + res = tklib.Tcl_UnsetVar2(self.interp, name1, name2, flags) + if res == tklib.TCL_ERROR: + self.raiseTclError() def getvar(self, name1, name2=None): return self._var_invoke(self._getvar, name1, name2) @@ -222,9 +258,10 @@ if self.threaded and self.thread_id != tklib.Tcl_GetCurrentThread(): raise NotImplementedError("Call from another thread") - res = tklib.Tcl_CreateCommand( - self.interp, cmdName.encode('utf-8'), _CommandData.PythonCmd, - clientData, _CommandData.PythonCmdDelete) + with self._tcl_lock: + res = tklib.Tcl_CreateCommand( + self.interp, cmdName.encode('utf-8'), _CommandData.PythonCmd, + clientData, _CommandData.PythonCmdDelete) if not res: raise TclError("can't create Tcl command") @@ -232,7 +269,8 @@ if self.threaded and self.thread_id != tklib.Tcl_GetCurrentThread(): raise NotImplementedError("Call from another thread") - res = tklib.Tcl_DeleteCommand(self.interp, cmdName.encode('utf-8')) + with self._tcl_lock: + res = tklib.Tcl_DeleteCommand(self.interp, cmdName.encode('utf-8')) if res == -1: raise TclError("can't delete Tcl command") @@ -259,11 +297,12 @@ tklib.Tcl_IncrRefCount(obj) objects[i] = obj - res = tklib.Tcl_EvalObjv(self.interp, argc, objects, flags) - if res == tklib.TCL_ERROR: - self.raiseTclError() - else: - result = self._callResult() + with self._tcl_lock: + res = tklib.Tcl_EvalObjv(self.interp, argc, objects, flags) + if res == tklib.TCL_ERROR: + self.raiseTclError() + else: + result = self._callResult() finally: for obj in objects: if obj: @@ -283,19 +322,21 @@ def eval(self, script): self._check_tcl_appartment() - res = tklib.Tcl_Eval(self.interp, script.encode('utf-8')) - if res == tklib.TCL_ERROR: - self.raiseTclError() - result = tkffi.string(tklib.Tcl_GetStringResult(self.interp)) - return result.decode('utf-8') + with self._tcl_lock: + res = tklib.Tcl_Eval(self.interp, script.encode('utf-8')) + if res == tklib.TCL_ERROR: + self.raiseTclError() + result = tkffi.string(tklib.Tcl_GetStringResult(self.interp)) + return result.decode('utf-8') def evalfile(self, filename): self._check_tcl_appartment() - res = tklib.Tcl_EvalFile(self.interp, filename.encode('utf-8')) - if res == tklib.TCL_ERROR: - self.raiseTclError() - result = tkffi.string(tklib.Tcl_GetStringResult(self.interp)) - return result.decode('utf-8') + with self._tcl_lock: + res = tklib.Tcl_EvalFile(self.interp, filename.encode('utf-8')) + if res == tklib.TCL_ERROR: + self.raiseTclError() + result = tkffi.string(tklib.Tcl_GetStringResult(self.interp)) + return result.decode('utf-8') def split(self, arg): if isinstance(arg, tuple): @@ -381,7 +422,10 @@ if self.threaded: result = tklib.Tcl_DoOneEvent(0) else: - raise NotImplementedError("TCL configured without threads") + with self._tcl_lock: + result = tklib.Tcl_DoOneEvent(tklib.TCL_DONT_WAIT) + if result == 0: + time.sleep(self._busywaitinterval) if result < 0: break diff --git a/lib_pypy/_tkinter/tklib.py b/lib_pypy/_tkinter/tklib.py --- a/lib_pypy/_tkinter/tklib.py +++ b/lib_pypy/_tkinter/tklib.py @@ -1,6 +1,7 @@ # C bindings with libtcl and libtk. from cffi import FFI +import sys tkffi = FFI() @@ -18,6 +19,8 @@ #define TCL_EVAL_DIRECT ... #define TCL_EVAL_GLOBAL ... +#define TCL_DONT_WAIT ... + typedef unsigned short Tcl_UniChar; typedef ... Tcl_Interp; typedef ...* Tcl_ThreadId; @@ -102,6 +105,17 @@ int Tk_GetNumMainWindows(); """) +# XXX find a better way to detect paths +# XXX pick up CPPFLAGS and LDFLAGS and add to these paths? +if sys.platform.startswith("openbsd"): + incdirs = ['/usr/local/include/tcl8.5', '/usr/local/include/tk8.5', '/usr/X11R6/include'] + linklibs = ['tk85', 'tcl85'] + libdirs = ['/usr/local/lib', '/usr/X11R6/lib'] +else: + incdirs=['/usr/include/tcl'] + linklibs=['tcl', 'tk'] + libdirs = [] + tklib = tkffi.verify(""" #include #include @@ -109,6 +123,7 @@ char *get_tk_version() { return TK_VERSION; } char *get_tcl_version() { return TCL_VERSION; } """, -include_dirs=['/usr/include/tcl'], -libraries=['tcl', 'tk'], +include_dirs=incdirs, +libraries=linklibs, +library_dirs = libdirs ) diff --git a/lib_pypy/cffi/__init__.py b/lib_pypy/cffi/__init__.py --- a/lib_pypy/cffi/__init__.py +++ b/lib_pypy/cffi/__init__.py @@ -4,5 +4,5 @@ from .api import FFI, CDefError, FFIError from .ffiplatform import VerificationError, VerificationMissing -__version__ = "0.7" -__version_info__ = (0, 7) +__version__ = "0.7.2" +__version_info__ = (0, 7, 2) diff --git a/lib_pypy/cffi/api.py b/lib_pypy/cffi/api.py --- a/lib_pypy/cffi/api.py +++ b/lib_pypy/cffi/api.py @@ -54,7 +54,8 @@ # _cffi_backend.so compiled. import _cffi_backend as backend from . import __version__ - assert backend.__version__ == __version__ + assert (backend.__version__ == __version__ or + backend.__version__ == __version__[:3]) # (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.) diff --git a/lib_pypy/cffi/commontypes.py b/lib_pypy/cffi/commontypes.py --- a/lib_pypy/cffi/commontypes.py +++ b/lib_pypy/cffi/commontypes.py @@ -30,7 +30,9 @@ elif result in model.PrimitiveType.ALL_PRIMITIVE_TYPES: result = model.PrimitiveType(result) else: - assert commontype != result + if commontype == result: + raise api.FFIError("Unsupported type: %r. Please file a bug " + "if you think it should be." % (commontype,)) result = resolve_common_type(result) # recursively assert isinstance(result, model.BaseTypeByIdentity) _CACHE[commontype] = result diff --git a/lib_pypy/cffi/cparser.py b/lib_pypy/cffi/cparser.py --- a/lib_pypy/cffi/cparser.py +++ b/lib_pypy/cffi/cparser.py @@ -290,13 +290,26 @@ # assume a primitive type. get it from .names, but reduce # synonyms to a single chosen combination names = list(type.names) - if names == ['signed'] or names == ['unsigned']: - names.append('int') - if names[0] == 'signed' and names != ['signed', 'char']: - names.pop(0) - if (len(names) > 1 and names[-1] == 'int' - and names != ['unsigned', 'int']): - names.pop() + if names != ['signed', 'char']: # keep this unmodified + prefixes = {} + while names: + name = names[0] + if name in ('short', 'long', 'signed', 'unsigned'): + prefixes[name] = prefixes.get(name, 0) + 1 + del names[0] + else: + break + # ignore the 'signed' prefix below, and reorder the others + newnames = [] + for prefix in ('unsigned', 'short', 'long'): + for i in range(prefixes.get(prefix, 0)): + newnames.append(prefix) + if not names: + names = ['int'] # implicitly + if names == ['int']: # but kill it if 'short' or 'long' + if 'short' in prefixes or 'long' in prefixes: + names = [] + names = newnames + names ident = ' '.join(names) if ident == 'void': return model.void_type @@ -500,8 +513,8 @@ self._partial_length = True return None # - raise api.FFIError("unsupported non-constant or " - "not immediately constant expression") + raise api.FFIError("unsupported expression: expected a " + "simple numeric constant") def _build_enum_type(self, explicit_name, decls): if decls is not None: diff --git a/lib_pypy/cffi/vengine_gen.py b/lib_pypy/cffi/vengine_gen.py --- a/lib_pypy/cffi/vengine_gen.py +++ b/lib_pypy/cffi/vengine_gen.py @@ -61,7 +61,9 @@ def load_library(self): # import it with the CFFI backend backend = self.ffi._backend - module = backend.load_library(self.verifier.modulefilename) + # needs to make a path that contains '/', on Posix + filename = os.path.join(os.curdir, self.verifier.modulefilename) + module = backend.load_library(filename) # # call loading_gen_struct() to get the struct layout inferred by # the C compiler diff --git a/pypy/config/pypyoption.py b/pypy/config/pypyoption.py --- a/pypy/config/pypyoption.py +++ b/pypy/config/pypyoption.py @@ -130,11 +130,6 @@ pypy_optiondescription = OptionDescription("objspace", "Object Space Options", [ - OptionDescription("opcodes", "opcodes to enable in the interpreter", [ - BoolOption("CALL_METHOD", "emit a special bytecode for expr.name()", - default=False), - ]), - OptionDescription("usemodules", "Which Modules should be used", [ BoolOption(modname, "use module %s" % (modname, ), default=modname in default_modules, @@ -253,9 +248,6 @@ BoolOption("optimized_int_add", "special case the addition of two integers in BINARY_ADD", default=False), - BoolOption("optimized_comparison_op", - "special case the comparison of integers", - default=False), BoolOption("optimized_list_getitem", "special case the 'list[integer]' expressions", default=False), @@ -301,7 +293,6 @@ # all the good optimizations for PyPy should be listed here if level in ['2', '3', 'jit']: - config.objspace.opcodes.suggest(CALL_METHOD=True) config.objspace.std.suggest(withmethodcache=True) config.objspace.std.suggest(withprebuiltchar=True) config.objspace.std.suggest(builtinshortcut=True) diff --git a/pypy/doc/config/objspace.opcodes.CALL_METHOD.txt b/pypy/doc/config/objspace.opcodes.CALL_METHOD.txt deleted file mode 100644 --- a/pypy/doc/config/objspace.opcodes.CALL_METHOD.txt +++ /dev/null @@ -1,10 +0,0 @@ -Enable a pair of bytecodes that speed up method calls. -See ``pypy.interpreter.callmethod`` for a description. - -The goal is to avoid creating the bound method object in the common -case. So far, this only works for calls with no keyword, no ``*arg`` -and no ``**arg`` but it would be easy to extend. - -For more information, see the section in `Standard Interpreter Optimizations`_. - -.. _`Standard Interpreter Optimizations`: ../interpreter-optimizations.html#lookup-method-call-method diff --git a/pypy/doc/config/objspace.opcodes.txt b/pypy/doc/config/objspace.opcodes.txt deleted file mode 100644 --- a/pypy/doc/config/objspace.opcodes.txt +++ /dev/null @@ -1,1 +0,0 @@ -.. intentionally empty 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 @@ -198,9 +198,6 @@ if it is not None, then it is considered to be an additional first argument in the call to the *im_func* object from the stack. -You can enable this feature with the :config:`objspace.opcodes.CALL_METHOD` -option. - .. more here? Overall Effects diff --git a/pypy/doc/tool/makecontributor.py b/pypy/doc/tool/makecontributor.py --- a/pypy/doc/tool/makecontributor.py +++ b/pypy/doc/tool/makecontributor.py @@ -60,6 +60,11 @@ 'Roberto De Ioris': ['roberto at mrspurr'], 'Sven Hager': ['hager'], 'Tomo Cocoa': ['cocoatomo'], + 'Romain Guillebert': ['rguillebert', 'rguillbert', 'romain', 'Guillebert Romain'], + 'Ronan Lamy': ['ronan'], + 'Edd Barrett': ['edd'], + 'Manuel Jacob': ['mjacob'], + 'Rami Chowdhury': ['necaris'], } alias_map = {} @@ -80,7 +85,8 @@ if not match: return set() ignore_words = ['around', 'consulting', 'yesterday', 'for a bit', 'thanks', - 'in-progress', 'bits of', 'even a little', 'floating',] + 'in-progress', 'bits of', 'even a little', 'floating', + 'a bit', 'reviewing'] sep_words = ['and', ';', '+', '/', 'with special by'] nicknames = match.group(1) for word in ignore_words: @@ -119,7 +125,7 @@ ## print '%5d %s' % (n, name) ## else: ## print name - + items = authors_count.items() items.sort(key=operator.itemgetter(1), reverse=True) for name, n in items: 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 @@ -5,6 +5,11 @@ .. this is a revision shortly after release-2.1-beta .. startrev: 4eb52818e7c0 +.. branch: sanitise_bytecode_dispatch +Make PyPy's bytecode dispatcher easy to read, and less reliant on RPython +magic. There is no functional change, though the removal of dead code leads +to many fewer tests to execute. + .. branch: fastjson Fast json decoder written in RPython, about 3-4x faster than the pure Python decoder which comes with the stdlib @@ -75,3 +80,18 @@ .. branch: reflex-support .. branch: numpypy-inplace-op .. branch: rewritten-loop-logging +.. branch: no-release-gil + +.. branch: nobold-backtrace +Work on improving UnionError messages and stack trace displays. + +.. branch: improve-errors-again +More improvements and refactorings of error messages. + +.. branch: improve-errors-again2 +Unbreak tests in rlib. + +.. branch: less-stringly-ops +Use subclasses of SpaceOperation instead of SpaceOperator objects. +Random cleanups in flowspace. + 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 @@ -1074,9 +1074,8 @@ return self._call_has_no_star_args(call) and not call.keywords def _optimize_method_call(self, call): - if not self.space.config.objspace.opcodes.CALL_METHOD or \ - not self._call_has_no_star_args(call) or \ - not isinstance(call.func, ast.Attribute): + if not self._call_has_no_star_args(call) or \ + not isinstance(call.func, ast.Attribute): return False attr_lookup = call.func assert isinstance(attr_lookup, ast.Attribute) diff --git a/pypy/interpreter/baseobjspace.py b/pypy/interpreter/baseobjspace.py --- a/pypy/interpreter/baseobjspace.py +++ b/pypy/interpreter/baseobjspace.py @@ -77,13 +77,12 @@ raise NotImplementedError("only for interp-level user subclasses " "from typedef.py") - def getname(self, space, default=u'?'): + def getname(self, space): try: return space.unicode_w(space.getattr(self, space.wrap('__name__'))) except OperationError, e: - if (e.match(space, space.w_TypeError) or - e.match(space, space.w_AttributeError)): - return default + if e.match(space, space.w_TypeError) or e.match(space, space.w_AttributeError): + return '?' raise def getaddrstring(self, space): diff --git a/pypy/interpreter/pycode.py b/pypy/interpreter/pycode.py --- a/pypy/interpreter/pycode.py +++ b/pypy/interpreter/pycode.py @@ -275,8 +275,10 @@ tuple(self.co_cellvars)) def exec_host_bytecode(self, w_globals, w_locals): - from pypy.interpreter.pyframe import CPythonFrame - frame = CPythonFrame(self.space, self, w_globals, None) + if sys.version_info < (2, 7): + raise Exception("PyPy no longer supports Python 2.6 or lower") + from pypy.interpreter.pyframe import PyFrame + frame = self.space.FrameClass(self.space, self, w_globals, None) frame.setdictscope(w_locals) return frame.run() diff --git a/pypy/interpreter/pyframe.py b/pypy/interpreter/pyframe.py --- a/pypy/interpreter/pyframe.py +++ b/pypy/interpreter/pyframe.py @@ -52,7 +52,7 @@ def __init__(self, space, code, w_globals, outer_func): if not we_are_translated(): - assert type(self) in (space.FrameClass, CPythonFrame), ( + assert type(self) == space.FrameClass, ( "use space.FrameClass(), not directly PyFrame()") self = hint(self, access_directly=True, fresh_virtualizable=True) assert isinstance(code, pycode.PyCode) @@ -677,17 +677,6 @@ return space.wrap(self.builtin is not space.builtin) return space.w_False -class CPythonFrame(PyFrame): - """ - Execution of host (CPython) opcodes. - """ - - bytecode_spec = host_bytecode_spec - opcode_method_names = host_bytecode_spec.method_names - opcodedesc = host_bytecode_spec.opcodedesc - opdescmap = host_bytecode_spec.opdescmap - HAVE_ARGUMENT = host_bytecode_spec.HAVE_ARGUMENT - # ____________________________________________________________ diff --git a/pypy/interpreter/pyopcode.py b/pypy/interpreter/pyopcode.py --- a/pypy/interpreter/pyopcode.py +++ b/pypy/interpreter/pyopcode.py @@ -13,10 +13,8 @@ from rpython.rlib.objectmodel import we_are_translated from rpython.rlib import jit, rstackovf from rpython.rlib.rarithmetic import r_uint, intmask -from rpython.rlib.unroll import unrolling_iterable from rpython.rlib.debug import check_nonneg -from pypy.tool.stdlib_opcode import (bytecode_spec, - unrolling_all_opcode_descs) +from pypy.tool.stdlib_opcode import bytecode_spec CANNOT_CATCH_MSG = ("catching classes that don't inherit from BaseException " "is not allowed in 3.x") @@ -44,34 +42,14 @@ return func_with_new_name(opimpl, "opcode_impl_for_%s" % operationname) -compare_dispatch_table = [ - "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_dispatch_table)) - +opcodedesc = bytecode_spec.opcodedesc +HAVE_ARGUMENT = bytecode_spec.HAVE_ARGUMENT class __extend__(pyframe.PyFrame): """A PyFrame that knows about interpretation of standard Python opcodes minus the ones related to nested scopes.""" - bytecode_spec = bytecode_spec - opcode_method_names = bytecode_spec.method_names - opcodedesc = bytecode_spec.opcodedesc - opdescmap = bytecode_spec.opdescmap - HAVE_ARGUMENT = bytecode_spec.HAVE_ARGUMENT - ### opcode dispatch ### def dispatch(self, pycode, next_instr, ec): @@ -174,7 +152,7 @@ #print 'executing', self.last_instr, bytecode_spec.method_names[opcode] next_instr += 1 - if opcode >= self.HAVE_ARGUMENT: + if opcode >= HAVE_ARGUMENT: lo = ord(co_code[next_instr]) hi = ord(co_code[next_instr+1]) next_instr += 2 @@ -184,19 +162,18 @@ # note: the structure of the code here is such that it makes # (after translation) a big "if/elif" chain, which is then - # turned into a switch(). It starts here: even if the first - # one is not an "if" but a "while" the effect is the same. + # turned into a switch(). - while opcode == self.opcodedesc.EXTENDED_ARG.index: + while opcode == opcodedesc.EXTENDED_ARG.index: opcode = ord(co_code[next_instr]) - if opcode < self.HAVE_ARGUMENT: + if opcode < HAVE_ARGUMENT: raise BytecodeCorruption lo = ord(co_code[next_instr+1]) hi = ord(co_code[next_instr+2]) next_instr += 3 oparg = (oparg * 65536) | (hi * 256) | lo - if opcode == self.opcodedesc.RETURN_VALUE.index: + if opcode == opcodedesc.RETURN_VALUE.index: w_returnvalue = self.popvalue() block = self.unrollstack(SReturnValue.kind) if block is None: @@ -206,8 +183,7 @@ unroller = SReturnValue(w_returnvalue) next_instr = block.handle(self, unroller) return next_instr # now inside a 'finally' block - - if opcode == self.opcodedesc.END_FINALLY.index: + elif opcode == opcodedesc.END_FINALLY.index: unroller = self.end_finally() if isinstance(unroller, SuspendedUnroller): # go on unrolling the stack @@ -219,49 +195,248 @@ else: next_instr = block.handle(self, unroller) return next_instr - - if opcode == self.opcodedesc.JUMP_ABSOLUTE.index: + elif opcode == opcodedesc.JUMP_ABSOLUTE.index: return self.jump_absolute(oparg, ec) - - if we_are_translated(): - for opdesc in unrolling_all_opcode_descs: - # static checks to skip this whole case if necessary - if opdesc.bytecode_spec is not self.bytecode_spec: - continue - if not opdesc.is_enabled(space): - continue - if opdesc.methodname in ( - 'EXTENDED_ARG', 'RETURN_VALUE', - 'END_FINALLY', 'JUMP_ABSOLUTE'): - continue # opcodes implemented above - - # the following "if" is part of the big switch described - # above. - if opcode == opdesc.index: - # dispatch to the opcode method - meth = getattr(self, opdesc.methodname) - res = meth(oparg, next_instr) - # !! warning, for the annotator the next line is not - # comparing an int and None - you can't do that. - # Instead, it's constant-folded to either True or False - if res is not None: - next_instr = res - break - else: - self.MISSING_OPCODE(oparg, next_instr) - - else: # when we are not translated, a list lookup is much faster - methodname = self.opcode_method_names[opcode] - try: - meth = getattr(self, methodname) - except AttributeError: - raise BytecodeCorruption("unimplemented opcode, ofs=%d, " - "code=%d, name=%s" % - (self.last_instr, opcode, - methodname)) - res = meth(oparg, next_instr) - if res is not None: - next_instr = res + elif opcode == opcodedesc.BREAK_LOOP.index: + next_instr = self.BREAK_LOOP(oparg, next_instr) + elif opcode == opcodedesc.CONTINUE_LOOP.index: + next_instr = self.CONTINUE_LOOP(oparg, next_instr) + elif opcode == opcodedesc.FOR_ITER.index: + next_instr = self.FOR_ITER(oparg, next_instr) + elif opcode == opcodedesc.JUMP_FORWARD.index: + next_instr = self.JUMP_FORWARD(oparg, next_instr) + elif opcode == opcodedesc.JUMP_IF_FALSE_OR_POP.index: + next_instr = self.JUMP_IF_FALSE_OR_POP(oparg, next_instr) + elif opcode == opcodedesc.JUMP_IF_NOT_DEBUG.index: + next_instr = self.JUMP_IF_NOT_DEBUG(oparg, next_instr) + elif opcode == opcodedesc.JUMP_IF_TRUE_OR_POP.index: + next_instr = self.JUMP_IF_TRUE_OR_POP(oparg, next_instr) + elif opcode == opcodedesc.POP_JUMP_IF_FALSE.index: + next_instr = self.POP_JUMP_IF_FALSE(oparg, next_instr) + elif opcode == opcodedesc.POP_JUMP_IF_TRUE.index: + next_instr = self.POP_JUMP_IF_TRUE(oparg, next_instr) + elif opcode == opcodedesc.BINARY_ADD.index: + self.BINARY_ADD(oparg, next_instr) + elif opcode == opcodedesc.BINARY_AND.index: + self.BINARY_AND(oparg, next_instr) + elif opcode == opcodedesc.BINARY_DIVIDE.index: + self.BINARY_DIVIDE(oparg, next_instr) + elif opcode == opcodedesc.BINARY_FLOOR_DIVIDE.index: + self.BINARY_FLOOR_DIVIDE(oparg, next_instr) + elif opcode == opcodedesc.BINARY_LSHIFT.index: + self.BINARY_LSHIFT(oparg, next_instr) + elif opcode == opcodedesc.BINARY_MODULO.index: + self.BINARY_MODULO(oparg, next_instr) + elif opcode == opcodedesc.BINARY_MULTIPLY.index: + self.BINARY_MULTIPLY(oparg, next_instr) + elif opcode == opcodedesc.BINARY_OR.index: + self.BINARY_OR(oparg, next_instr) + elif opcode == opcodedesc.BINARY_POWER.index: + self.BINARY_POWER(oparg, next_instr) + elif opcode == opcodedesc.BINARY_RSHIFT.index: + self.BINARY_RSHIFT(oparg, next_instr) + elif opcode == opcodedesc.BINARY_SUBSCR.index: + self.BINARY_SUBSCR(oparg, next_instr) + elif opcode == opcodedesc.BINARY_SUBTRACT.index: + self.BINARY_SUBTRACT(oparg, next_instr) + elif opcode == opcodedesc.BINARY_TRUE_DIVIDE.index: + self.BINARY_TRUE_DIVIDE(oparg, next_instr) + elif opcode == opcodedesc.BINARY_XOR.index: + self.BINARY_XOR(oparg, next_instr) + elif opcode == opcodedesc.BUILD_CLASS.index: + self.BUILD_CLASS(oparg, next_instr) + elif opcode == opcodedesc.BUILD_LIST.index: + self.BUILD_LIST(oparg, next_instr) + elif opcode == opcodedesc.BUILD_LIST_FROM_ARG.index: + self.BUILD_LIST_FROM_ARG(oparg, next_instr) + elif opcode == opcodedesc.BUILD_MAP.index: + self.BUILD_MAP(oparg, next_instr) + elif opcode == opcodedesc.BUILD_SET.index: + self.BUILD_SET(oparg, next_instr) + elif opcode == opcodedesc.BUILD_SLICE.index: + self.BUILD_SLICE(oparg, next_instr) + elif opcode == opcodedesc.BUILD_TUPLE.index: + self.BUILD_TUPLE(oparg, next_instr) + elif opcode == opcodedesc.CALL_FUNCTION.index: + self.CALL_FUNCTION(oparg, next_instr) + elif opcode == opcodedesc.CALL_FUNCTION_KW.index: + self.CALL_FUNCTION_KW(oparg, next_instr) + elif opcode == opcodedesc.CALL_FUNCTION_VAR.index: + self.CALL_FUNCTION_VAR(oparg, next_instr) + elif opcode == opcodedesc.CALL_FUNCTION_VAR_KW.index: + self.CALL_FUNCTION_VAR_KW(oparg, next_instr) + elif opcode == opcodedesc.CALL_METHOD.index: + self.CALL_METHOD(oparg, next_instr) + elif opcode == opcodedesc.COMPARE_OP.index: + self.COMPARE_OP(oparg, next_instr) + elif opcode == opcodedesc.DELETE_ATTR.index: + self.DELETE_ATTR(oparg, next_instr) + elif opcode == opcodedesc.DELETE_FAST.index: + self.DELETE_FAST(oparg, next_instr) + elif opcode == opcodedesc.DELETE_GLOBAL.index: + self.DELETE_GLOBAL(oparg, next_instr) + elif opcode == opcodedesc.DELETE_NAME.index: + self.DELETE_NAME(oparg, next_instr) + elif opcode == opcodedesc.DELETE_SLICE_0.index: + self.DELETE_SLICE_0(oparg, next_instr) + elif opcode == opcodedesc.DELETE_SLICE_1.index: + self.DELETE_SLICE_1(oparg, next_instr) + elif opcode == opcodedesc.DELETE_SLICE_2.index: + self.DELETE_SLICE_2(oparg, next_instr) + elif opcode == opcodedesc.DELETE_SLICE_3.index: + self.DELETE_SLICE_3(oparg, next_instr) + elif opcode == opcodedesc.DELETE_SUBSCR.index: + self.DELETE_SUBSCR(oparg, next_instr) + elif opcode == opcodedesc.DUP_TOP.index: + self.DUP_TOP(oparg, next_instr) + elif opcode == opcodedesc.DUP_TOPX.index: + self.DUP_TOPX(oparg, next_instr) + elif opcode == opcodedesc.EXEC_STMT.index: + self.EXEC_STMT(oparg, next_instr) + elif opcode == opcodedesc.GET_ITER.index: + self.GET_ITER(oparg, next_instr) + elif opcode == opcodedesc.IMPORT_FROM.index: + self.IMPORT_FROM(oparg, next_instr) + elif opcode == opcodedesc.IMPORT_NAME.index: + self.IMPORT_NAME(oparg, next_instr) + elif opcode == opcodedesc.IMPORT_STAR.index: + self.IMPORT_STAR(oparg, next_instr) + elif opcode == opcodedesc.INPLACE_ADD.index: + self.INPLACE_ADD(oparg, next_instr) + elif opcode == opcodedesc.INPLACE_AND.index: + self.INPLACE_AND(oparg, next_instr) + elif opcode == opcodedesc.INPLACE_DIVIDE.index: + self.INPLACE_DIVIDE(oparg, next_instr) + elif opcode == opcodedesc.INPLACE_FLOOR_DIVIDE.index: + self.INPLACE_FLOOR_DIVIDE(oparg, next_instr) + elif opcode == opcodedesc.INPLACE_LSHIFT.index: + self.INPLACE_LSHIFT(oparg, next_instr) + elif opcode == opcodedesc.INPLACE_MODULO.index: + self.INPLACE_MODULO(oparg, next_instr) + elif opcode == opcodedesc.INPLACE_MULTIPLY.index: + self.INPLACE_MULTIPLY(oparg, next_instr) + elif opcode == opcodedesc.INPLACE_OR.index: + self.INPLACE_OR(oparg, next_instr) + elif opcode == opcodedesc.INPLACE_POWER.index: + self.INPLACE_POWER(oparg, next_instr) + elif opcode == opcodedesc.INPLACE_RSHIFT.index: + self.INPLACE_RSHIFT(oparg, next_instr) + elif opcode == opcodedesc.INPLACE_SUBTRACT.index: + self.INPLACE_SUBTRACT(oparg, next_instr) + elif opcode == opcodedesc.INPLACE_TRUE_DIVIDE.index: + self.INPLACE_TRUE_DIVIDE(oparg, next_instr) + elif opcode == opcodedesc.INPLACE_XOR.index: + self.INPLACE_XOR(oparg, next_instr) + elif opcode == opcodedesc.LIST_APPEND.index: + self.LIST_APPEND(oparg, next_instr) + elif opcode == opcodedesc.LOAD_ATTR.index: + self.LOAD_ATTR(oparg, next_instr) + elif opcode == opcodedesc.LOAD_CLOSURE.index: + self.LOAD_CLOSURE(oparg, next_instr) + elif opcode == opcodedesc.LOAD_CONST.index: + self.LOAD_CONST(oparg, next_instr) + elif opcode == opcodedesc.LOAD_DEREF.index: + self.LOAD_DEREF(oparg, next_instr) + elif opcode == opcodedesc.LOAD_FAST.index: + self.LOAD_FAST(oparg, next_instr) + elif opcode == opcodedesc.LOAD_GLOBAL.index: + self.LOAD_GLOBAL(oparg, next_instr) + elif opcode == opcodedesc.LOAD_LOCALS.index: + self.LOAD_LOCALS(oparg, next_instr) + elif opcode == opcodedesc.LOAD_NAME.index: + self.LOAD_NAME(oparg, next_instr) + elif opcode == opcodedesc.LOOKUP_METHOD.index: + self.LOOKUP_METHOD(oparg, next_instr) + elif opcode == opcodedesc.MAKE_CLOSURE.index: + self.MAKE_CLOSURE(oparg, next_instr) + elif opcode == opcodedesc.MAKE_FUNCTION.index: + self.MAKE_FUNCTION(oparg, next_instr) + elif opcode == opcodedesc.MAP_ADD.index: + self.MAP_ADD(oparg, next_instr) + elif opcode == opcodedesc.NOP.index: + self.NOP(oparg, next_instr) + elif opcode == opcodedesc.POP_BLOCK.index: + self.POP_BLOCK(oparg, next_instr) + elif opcode == opcodedesc.POP_TOP.index: + self.POP_TOP(oparg, next_instr) + elif opcode == opcodedesc.PRINT_EXPR.index: + self.PRINT_EXPR(oparg, next_instr) + elif opcode == opcodedesc.PRINT_ITEM.index: + self.PRINT_ITEM(oparg, next_instr) + elif opcode == opcodedesc.PRINT_ITEM_TO.index: + self.PRINT_ITEM_TO(oparg, next_instr) + elif opcode == opcodedesc.PRINT_NEWLINE.index: + self.PRINT_NEWLINE(oparg, next_instr) + elif opcode == opcodedesc.PRINT_NEWLINE_TO.index: + self.PRINT_NEWLINE_TO(oparg, next_instr) + elif opcode == opcodedesc.RAISE_VARARGS.index: + self.RAISE_VARARGS(oparg, next_instr) + elif opcode == opcodedesc.ROT_FOUR.index: + self.ROT_FOUR(oparg, next_instr) + elif opcode == opcodedesc.ROT_THREE.index: + self.ROT_THREE(oparg, next_instr) + elif opcode == opcodedesc.ROT_TWO.index: + self.ROT_TWO(oparg, next_instr) + elif opcode == opcodedesc.SETUP_EXCEPT.index: + self.SETUP_EXCEPT(oparg, next_instr) + elif opcode == opcodedesc.SETUP_FINALLY.index: + self.SETUP_FINALLY(oparg, next_instr) + elif opcode == opcodedesc.SETUP_LOOP.index: + self.SETUP_LOOP(oparg, next_instr) + elif opcode == opcodedesc.SETUP_WITH.index: + self.SETUP_WITH(oparg, next_instr) + elif opcode == opcodedesc.SET_ADD.index: + self.SET_ADD(oparg, next_instr) + elif opcode == opcodedesc.SLICE_0.index: + self.SLICE_0(oparg, next_instr) + elif opcode == opcodedesc.SLICE_1.index: + self.SLICE_1(oparg, next_instr) + elif opcode == opcodedesc.SLICE_2.index: + self.SLICE_2(oparg, next_instr) + elif opcode == opcodedesc.SLICE_3.index: + self.SLICE_3(oparg, next_instr) + elif opcode == opcodedesc.STOP_CODE.index: + self.STOP_CODE(oparg, next_instr) + elif opcode == opcodedesc.STORE_ATTR.index: + self.STORE_ATTR(oparg, next_instr) + elif opcode == opcodedesc.STORE_DEREF.index: + self.STORE_DEREF(oparg, next_instr) + elif opcode == opcodedesc.STORE_FAST.index: + self.STORE_FAST(oparg, next_instr) + elif opcode == opcodedesc.STORE_GLOBAL.index: + self.STORE_GLOBAL(oparg, next_instr) + elif opcode == opcodedesc.STORE_MAP.index: + self.STORE_MAP(oparg, next_instr) + elif opcode == opcodedesc.STORE_NAME.index: + self.STORE_NAME(oparg, next_instr) + elif opcode == opcodedesc.STORE_SLICE_0.index: + self.STORE_SLICE_0(oparg, next_instr) + elif opcode == opcodedesc.STORE_SLICE_1.index: + self.STORE_SLICE_1(oparg, next_instr) + elif opcode == opcodedesc.STORE_SLICE_2.index: + self.STORE_SLICE_2(oparg, next_instr) + elif opcode == opcodedesc.STORE_SLICE_3.index: + self.STORE_SLICE_3(oparg, next_instr) + elif opcode == opcodedesc.STORE_SUBSCR.index: + self.STORE_SUBSCR(oparg, next_instr) + elif opcode == opcodedesc.UNARY_CONVERT.index: + self.UNARY_CONVERT(oparg, next_instr) + elif opcode == opcodedesc.UNARY_INVERT.index: + self.UNARY_INVERT(oparg, next_instr) + elif opcode == opcodedesc.UNARY_NEGATIVE.index: + self.UNARY_NEGATIVE(oparg, next_instr) + elif opcode == opcodedesc.UNARY_NOT.index: + self.UNARY_NOT(oparg, next_instr) + elif opcode == opcodedesc.UNARY_POSITIVE.index: + self.UNARY_POSITIVE(oparg, next_instr) + elif opcode == opcodedesc.UNPACK_SEQUENCE.index: + self.UNPACK_SEQUENCE(oparg, next_instr) + elif opcode == opcodedesc.WITH_CLEANUP.index: + self.WITH_CLEANUP(oparg, next_instr) + elif opcode == opcodedesc.YIELD_VALUE.index: + self.YIELD_VALUE(oparg, next_instr) + else: + self.MISSING_OPCODE(oparg, next_instr) if jit.we_are_jitted(): return next_instr @@ -714,36 +889,6 @@ self.pushvalue(w_value) LOAD_ATTR._always_inline_ = True - def cmp_lt(self, w_1, w_2): - return self.space.lt(w_1, w_2) - - def cmp_le(self, w_1, w_2): - return self.space.le(w_1, w_2) - - def cmp_eq(self, w_1, w_2): - return self.space.eq(w_1, w_2) - - def cmp_ne(self, w_1, w_2): - return self.space.ne(w_1, w_2) - - def cmp_gt(self, w_1, w_2): - return self.space.gt(w_1, w_2) - - def cmp_ge(self, w_1, w_2): - return self.space.ge(w_1, w_2) - - def cmp_in(self, w_1, w_2): - return self.space.contains(w_2, w_1) - - def cmp_not_in(self, w_1, w_2): - return self.space.not_(self.space.contains(w_2, w_1)) - - def cmp_is(self, w_1, w_2): - return self.space.is_(w_1, w_2) - - def cmp_is_not(self, w_1, w_2): - return self.space.not_(self.space.is_(w_1, w_2)) - @jit.unroll_safe def cmp_exc_match(self, w_1, w_2): space = self.space @@ -760,11 +905,28 @@ def COMPARE_OP(self, testnum, next_instr): w_2 = self.popvalue() w_1 = self.popvalue() - w_result = None - for i, attr in unrolling_compare_dispatch_table: - if i == testnum: - w_result = getattr(self, attr)(w_1, w_2) - break + if testnum == 0: + w_result = self.space.lt(w_1, w_2) + elif testnum == 1: + w_result = self.space.le(w_1, w_2) + elif testnum == 2: + w_result = self.space.eq(w_1, w_2) + elif testnum == 3: + w_result = self.space.ne(w_1, w_2) + elif testnum == 4: + w_result = self.space.gt(w_1, w_2) + elif testnum == 5: + w_result = self.space.ge(w_1, w_2) + elif testnum == 6: + w_result = self.space.contains(w_2, w_1) + elif testnum == 7: + w_result = self.space.not_(self.space.contains(w_2, w_1)) + elif testnum == 8: + w_result = self.space.is_(w_1, w_2) + elif testnum == 9: + w_result = self.space.not_(self.space.is_(w_1, w_2)) + elif testnum == 10: + w_result = self.cmp_exc_match(w_1, w_2) else: raise BytecodeCorruption("bad COMPARE_OP oparg") self.pushvalue(w_result) @@ -1095,49 +1257,6 @@ self.space.setitem(w_dict, w_key, w_value) -class __extend__(pyframe.CPythonFrame): - - def JUMP_IF_FALSE(self, stepby, next_instr): - w_cond = self.peekvalue() - if not self.space.is_true(w_cond): - next_instr += stepby - return next_instr - - def JUMP_IF_TRUE(self, stepby, next_instr): - w_cond = self.peekvalue() - if self.space.is_true(w_cond): - next_instr += stepby - return next_instr - - def BUILD_MAP(self, itemcount, next_instr): - if sys.version_info >= (2, 6): - # We could pre-allocate a dict here - # but for the moment this code is not translated. - pass - else: - if itemcount != 0: - raise BytecodeCorruption - w_dict = self.space.newdict() - self.pushvalue(w_dict) - - def STORE_MAP(self, zero, next_instr): - if sys.version_info >= (2, 6): - w_key = self.popvalue() - w_value = self.popvalue() - w_dict = self.peekvalue() - self.space.setitem(w_dict, w_key, w_value) - else: - raise BytecodeCorruption - - def LIST_APPEND(self, oparg, next_instr): - w = self.popvalue() - if sys.version_info < (2, 7): - v = self.popvalue() - else: - v = self.peekvalue(oparg - 1) - self.space.call_method(v, 'append', w) - - ### ____________________________________________________________ ### class ExitFrame(Exception): diff --git a/pypy/interpreter/test/test_argument.py b/pypy/interpreter/test/test_argument.py --- a/pypy/interpreter/test/test_argument.py +++ b/pypy/interpreter/test/test_argument.py @@ -135,7 +135,7 @@ def type(self, obj): class Type: - def getname(self, space, default=u'?'): + def getname(self, space): return unicode(type(obj).__name__) return Type() 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 @@ -1075,10 +1075,6 @@ assert i > -1 assert isinstance(co.co_consts[i], frozenset) - -class AppTestCallMethod(object): - spaceconfig = {'objspace.opcodes.CALL_METHOD': True} - def test_call_method_kwargs(self): source = """def _f(a): return a.f(a=a) diff --git a/pypy/interpreter/test/test_executioncontext.py b/pypy/interpreter/test/test_executioncontext.py --- a/pypy/interpreter/test/test_executioncontext.py +++ b/pypy/interpreter/test/test_executioncontext.py @@ -254,10 +254,6 @@ """) -class TestExecutionContextWithCallMethod(TestExecutionContext): - spaceconfig ={'objspace.opcodes.CALL_METHOD': True} - - class AppTestDelNotBlocked: def setup_method(self, meth): 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 @@ -844,9 +844,6 @@ assert len(called) == 1 assert isinstance(called[0], argument.Arguments) -class TestPassThroughArguments_CALL_METHOD(TestPassThroughArguments): - spaceconfig = {"objspace.opcodes.CALL_METHOD": True} - class AppTestKeywordsToBuiltinSanity(object): diff --git a/pypy/module/_cffi_backend/ccallback.py b/pypy/module/_cffi_backend/ccallback.py --- a/pypy/module/_cffi_backend/ccallback.py +++ b/pypy/module/_cffi_backend/ccallback.py @@ -54,6 +54,13 @@ if rffi.cast(lltype.Signed, res) != clibffi.FFI_OK: raise OperationError(space.w_SystemError, space.wrap("libffi failed to build this callback")) + # + # We must setup the GIL here, in case the callback is invoked in + # some other non-Pythonic thread. This is the same as cffi on + # CPython. + if space.config.translation.thread: + from pypy.module.thread.os_thread import setup_threads + setup_threads(space) def get_closure(self): return rffi.cast(clibffi.FFI_CLOSUREP, self._cdata) 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 @@ -1516,13 +1516,18 @@ d = BStruct.fields assert d[0][1].offset == d[1][1].offset == d[2][1].offset == 0 assert d[3][1].offset == sizeof(BLong) - assert d[0][1].bitshift == 0 + def f(m, r): + if sys.byteorder == 'little': + return r + else: + return LONGBITS - m - r + assert d[0][1].bitshift == f(1, 0) assert d[0][1].bitsize == 1 - assert d[1][1].bitshift == 1 + assert d[1][1].bitshift == f(2, 1) assert d[1][1].bitsize == 2 - assert d[2][1].bitshift == 3 + assert d[2][1].bitshift == f(3, 3) assert d[2][1].bitsize == 3 - assert d[3][1].bitshift == 0 + assert d[3][1].bitshift == f(LONGBITS - 5, 0) assert d[3][1].bitsize == LONGBITS - 5 assert sizeof(BStruct) == 2 * sizeof(BLong) assert alignof(BStruct) == alignof(BLong) @@ -2856,7 +2861,7 @@ ('b1', BInt, 9), ('b2', BUInt, 7), ('c', BChar, -1)], -1, -1, -1, flag) - if flag % 2 == 0: # gcc and gcc ARM + if flag % 2 == 0: # gcc, any variant assert typeoffsetof(BStruct, 'c') == (BChar, 3) assert sizeof(BStruct) == 4 else: # msvc @@ -2864,6 +2869,31 @@ assert sizeof(BStruct) == 12 assert alignof(BStruct) == 4 # + p = newp(new_pointer_type(BStruct), None) + p.a = b'A' + p.b1 = -201 + p.b2 = 99 + p.c = b'\x9D' + raw = buffer(p)[:] + if sys.byteorder == 'little': + if flag == 0 or flag == 2: # gcc, little endian + assert raw == b'A7\xC7\x9D' + elif flag == 1: # msvc + assert raw == b'A\x00\x00\x007\xC7\x00\x00\x9D\x00\x00\x00' + elif flag == 4: # gcc, big endian + assert raw == b'A\xE3\x9B\x9D' + else: + raise AssertionError("bad flag") + else: + if flag == 0 or flag == 2: # gcc + assert raw == b'A\xC77\x9D' + elif flag == 1: # msvc + assert raw == b'A\x00\x00\x00\x00\x00\xC77\x9D\x00\x00\x00' + elif flag == 4: # gcc, big endian + assert raw == b'A\x9B\xE3\x9D' + else: + raise AssertionError("bad flag") + # BStruct = new_struct_type("struct foo2") complete_struct_or_union(BStruct, [('a', BChar, -1), ('', BShort, 9), @@ -2875,16 +2905,21 @@ elif flag == 1: # msvc assert sizeof(BStruct) == 6 assert alignof(BStruct) == 2 - else: # gcc ARM + elif flag == 2: # gcc ARM assert sizeof(BStruct) == 6 assert alignof(BStruct) == 2 + elif flag == 4: # gcc, big endian + assert sizeof(BStruct) == 5 + assert alignof(BStruct) == 1 + else: + raise AssertionError("bad flag") # BStruct = new_struct_type("struct foo2") complete_struct_or_union(BStruct, [('a', BChar, -1), ('', BInt, 0), ('', BInt, 0), ('c', BChar, -1)], -1, -1, -1, flag) - if flag == 0: # gcc + if flag == 0: # gcc assert typeoffsetof(BStruct, 'c') == (BChar, 4) assert sizeof(BStruct) == 5 assert alignof(BStruct) == 1 @@ -2892,10 +2927,16 @@ assert typeoffsetof(BStruct, 'c') == (BChar, 1) assert sizeof(BStruct) == 2 assert alignof(BStruct) == 1 - else: # gcc ARM + elif flag == 2: # gcc ARM assert typeoffsetof(BStruct, 'c') == (BChar, 4) assert sizeof(BStruct) == 8 assert alignof(BStruct) == 4 + elif flag == 4: # gcc, big endian + assert typeoffsetof(BStruct, 'c') == (BChar, 4) + assert sizeof(BStruct) == 5 + assert alignof(BStruct) == 1 + else: + raise AssertionError("bad flag") def test_bitfield_as_gcc(): @@ -2907,6 +2948,11 @@ def test_bitfield_as_arm_gcc(): _test_bitfield_details(flag=2) +def test_bitfield_as_big_endian(): + if '__pypy__' in sys.builtin_module_names: + py.test.skip("no big endian machine supported on pypy for now") + _test_bitfield_details(flag=4) + def test_version(): # this test is here mostly for PyPy diff --git a/pypy/module/_continuation/interp_pickle.py b/pypy/module/_continuation/interp_pickle.py --- a/pypy/module/_continuation/interp_pickle.py +++ b/pypy/module/_continuation/interp_pickle.py @@ -120,8 +120,7 @@ nkwds = (oparg >> 8) & 0xff if nkwds == 0: # only positional arguments # fast paths leaves things on the stack, pop them - if (frame.space.config.objspace.opcodes.CALL_METHOD and - opcode == map['CALL_METHOD']): + if opcode == map['CALL_METHOD']: frame.dropvalues(nargs + 2) elif opcode == map['CALL_FUNCTION']: frame.dropvalues(nargs + 1) diff --git a/pypy/module/_continuation/test/test_zpickle.py b/pypy/module/_continuation/test/test_zpickle.py --- a/pypy/module/_continuation/test/test_zpickle.py +++ b/pypy/module/_continuation/test/test_zpickle.py @@ -3,8 +3,7 @@ class AppTestCopy: spaceconfig = dict(usemodules=['_continuation'], - continuation=True, - CALL_METHOD=True) + continuation=True) def test_basic_setup(self): from _continuation import continulet @@ -106,7 +105,6 @@ spaceconfig = { "usemodules": ['_continuation', 'struct', 'binascii'], "continuation": True, - "CALL_METHOD": True, } def setup_class(cls): diff --git a/pypy/module/_lsprof/test/test_cprofile.py b/pypy/module/_lsprof/test/test_cprofile.py --- a/pypy/module/_lsprof/test/test_cprofile.py +++ b/pypy/module/_lsprof/test/test_cprofile.py @@ -191,11 +191,6 @@ sys.path.pop(0) -class AppTestWithDifferentBytecodes(AppTestCProfile): - spaceconfig = AppTestCProfile.spaceconfig.copy() - spaceconfig['objspace.opcodes.CALL_METHOD'] = True - - expected_output = {} expected_output['print_stats'] = """\ 119 function calls (99 primitive calls) in 1.000 seconds 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 @@ -26,6 +26,9 @@ def try_ldflags(): yield ExternalCompilationInfo(libraries=['curses']) yield ExternalCompilationInfo(libraries=['curses', 'tinfo']) + yield ExternalCompilationInfo(libraries=['ncurses']) + yield ExternalCompilationInfo(libraries=['ncurses'], + library_dirs=['/usr/lib64']) def try_tools(): try: 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 @@ -175,8 +175,8 @@ state = u'; dead' else: typename = space.type(w_obj).getname(space) - objname = w_obj.getname(space, u'') - if objname: + objname = w_obj.getname(space) + if objname and objname != u'?': state = u"; to '%s' (%s)" % (typename, objname) else: state = u"; to '%s'" % (typename,) diff --git a/pypy/module/cpyext/pystate.py b/pypy/module/cpyext/pystate.py --- a/pypy/module/cpyext/pystate.py +++ b/pypy/module/cpyext/pystate.py @@ -245,7 +245,6 @@ it is necessary to serialize calls to this function.""" if not space.config.translation.thread: raise NoThreads - rthread.gc_thread_prepare() # PyThreadState_Get will allocate a new execution context, # we need to protect gc and other globals with the GIL. rffi.aroundstate.after() 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 @@ -854,8 +854,7 @@ # # default_magic - 6 -- used by CPython without the -U option # default_magic - 5 -- used by CPython with the -U option -# default_magic -- used by PyPy without the CALL_METHOD opcode -# default_magic + 2 -- used by PyPy with the CALL_METHOD opcode +# default_magic -- used by PyPy [because of CALL_METHOD] # from pypy.interpreter.pycode import default_magic MARSHAL_VERSION_FOR_PYC = 2 @@ -868,10 +867,7 @@ magic = __import__('imp').get_magic() return struct.unpack(' 1 and idx.get_shape() != self.get_shape(): raise OperationError(space.w_ValueError, space.wrap("boolean index array should have 1 dimension")) if idx.get_size() > self.get_size(): raise OperationError(space.w_ValueError, space.wrap("index out of range for array")) + idx_iter = idx.create_iter(self.get_shape()) + size = loop.count_all_true_iter(idx_iter, self.get_shape(), idx.get_dtype()) + if len(val.get_shape()) > 0 and val.get_shape()[0] > 1 and size > val.get_shape()[0]: + raise OperationError(space.w_ValueError, space.wrap("NumPy boolean array indexing assignment " + "cannot assign %d input values to " + "the %d output values where the mask is true" % (val.get_shape()[0],size))) + if val.get_shape() == [1]: + box = val.descr_getitem(space, space.wrap(0)) + assert isinstance(box, Box) + val = W_NDimArray(scalar.Scalar(val.get_dtype(), box)) + elif val.get_shape() == [0]: + val.implementation.dtype = self.implementation.dtype loop.setitem_filter(self, idx, val) def _prepare_array_index(self, space, w_index): 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 @@ -132,7 +132,7 @@ reduce_driver = jit.JitDriver(name='numpy_reduce', greens = ['shapelen', 'func', 'done_func', - 'calc_dtype', 'identity'], + 'calc_dtype'], reds = 'auto') def compute_reduce(obj, calc_dtype, func, done_func, identity): @@ -146,7 +146,7 @@ while not obj_iter.done(): reduce_driver.jit_merge_point(shapelen=shapelen, func=func, done_func=done_func, - calc_dtype=calc_dtype, identity=identity, + calc_dtype=calc_dtype, ) rval = obj_iter.getitem().convert_to(calc_dtype) if done_func is not None and done_func(calc_dtype, rval): @@ -318,23 +318,27 @@ lefti.next() return result -count_all_true_driver = jit.JitDriver(name = 'numpy_count', - greens = ['shapelen', 'dtype'], - reds = 'auto') def count_all_true(arr): - s = 0 if arr.is_scalar(): return arr.get_dtype().itemtype.bool(arr.get_scalar_value()) iter = arr.create_iter() - shapelen = len(arr.get_shape()) - dtype = arr.get_dtype() + return count_all_true_iter(iter, arr.get_shape(), arr.get_dtype()) + +count_all_true_iter_driver = jit.JitDriver(name = 'numpy_count', + greens = ['shapelen', 'dtype'], + reds = 'auto') +def count_all_true_iter(iter, shape, dtype): + s = 0 + shapelen = len(shape) + dtype = dtype while not iter.done(): - count_all_true_driver.jit_merge_point(shapelen=shapelen, dtype=dtype) + count_all_true_iter_driver.jit_merge_point(shapelen=shapelen, dtype=dtype) s += iter.getitem_bool() iter.next() return s + getitem_filter_driver = jit.JitDriver(name = 'numpy_getitem_bool', greens = ['shapelen', 'arr_dtype', 'index_dtype'], @@ -370,7 +374,7 @@ def setitem_filter(arr, index, value): arr_iter = arr.create_iter() - index_iter = index.create_iter() + index_iter = index.create_iter(arr.get_shape()) value_iter = value.create_iter() shapelen = len(arr.get_shape()) index_dtype = index.get_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 @@ -1928,6 +1928,23 @@ a.fill(12) assert (a == '1').all() + def test_boolean_indexing(self): + import numpypy as np + a = np.zeros((1, 3)) + b = np.array([True]) + + assert (a[b] == a).all() + + a[b] = 1. + + assert (a == [[1., 1., 1.]]).all() + + @py.test.mark.xfail + def test_boolean_array(self): + import numpypy as np + a = np.ndarray([1], dtype=bool) + assert a[0] == True + class AppTestMultiDim(BaseNumpyAppTest): def test_init(self): import numpypy @@ -2335,6 +2352,21 @@ a[a & 1 == 0] = 15 assert (a == [[15, 1], [15, 5], [15, 9]]).all() + def test_array_indexing_bool_specialcases(self): + from numpypy import arange, array + a = arange(6) + try: + a[a < 3] = [1, 2] + assert False, "Should not work" + except ValueError: + pass + a = arange(6) + a[a > 3] = array([15]) + assert (a == [0, 1, 2, 3, 15, 15]).all() + a = arange(6).reshape(3, 2) + a[a & 1 == 1] = [] # here, Numpy sticks garbage into the array + assert a.shape == (3, 2) + def test_copy_kwarg(self): from numpypy import array x = array([1, 2, 3]) diff --git a/pypy/module/micronumpy/test/test_zjit.py b/pypy/module/micronumpy/test/test_zjit.py --- a/pypy/module/micronumpy/test/test_zjit.py +++ b/pypy/module/micronumpy/test/test_zjit.py @@ -56,7 +56,7 @@ elif isinstance(w_res, interp_boxes.W_BoolBox): return float(w_res.value) raise TypeError(w_res) - + if self.graph is None: interp, graph = self.meta_interp(f, [0], listops=True, @@ -139,11 +139,17 @@ 'int_add': 3, }) + def define_reduce(): + return """ + a = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10] + sum(a) + """ + def test_reduce_compile_only_once(self): self.compile_graph() reset_stats() pyjitpl._warmrunnerdesc.memory_manager.alive_loops.clear() - i = self.code_mapping['sum'] + i = self.code_mapping['reduce'] # run it twice retval = self.interp.eval_graph(self.graph, [i]) retval = self.interp.eval_graph(self.graph, [i]) 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 @@ -109,7 +109,8 @@ 'posix', '_socket', '_sre', '_lsprof', '_weakref', '__pypy__', 'cStringIO', '_collections', 'struct', 'mmap', 'marshal', '_codecs', 'rctime', 'cppyy', - '_cffi_backend', 'pyexpat', '_continuation', '_io']: + '_cffi_backend', 'pyexpat', '_continuation', '_io', + 'thread']: if modname == 'pypyjit' and 'interp_resop' in rest: return False return True diff --git a/pypy/module/pypyjit/test/test_policy.py b/pypy/module/pypyjit/test/test_policy.py --- a/pypy/module/pypyjit/test/test_policy.py +++ b/pypy/module/pypyjit/test/test_policy.py @@ -45,6 +45,10 @@ from pypy.module._io.interp_bytesio import W_BytesIO assert pypypolicy.look_inside_function(W_BytesIO.seek_w.im_func) +def test_thread(): + from pypy.module.thread.os_lock import Lock + assert pypypolicy.look_inside_function(Lock.descr_lock_acquire.im_func) + def test_pypy_module(): from pypy.module._collections.interp_deque import W_Deque from pypy.module._random.interp_random import W_Random 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 @@ -1,5 +1,3 @@ - -import py, sys from pypy.module.pypyjit.test_pypy_c.test_00_model import BaseTestPyPyC @@ -51,27 +49,6 @@ ... """) - def test_list(self): - def main(n): - i = 0 - while i < n: - z = list(()) - z.append(1) - i += z[-1] / len(z) - return i - - log = self.run(main, [1000]) - assert log.result == main(1000) - loop, = log.loops_by_filename(self.filepath) - assert loop.match(""" - i7 = int_lt(i5, i6) - guard_true(i7, descr=...) - guard_not_invalidated(descr=...) - i9 = int_add(i5, 1) - --TICK-- - jump(..., descr=...) - """) - def test_non_virtual_dict(self): def main(n): i = 0 @@ -119,6 +96,30 @@ jump(..., descr=...) """) + + +class TestOtherContainers(BaseTestPyPyC): + def test_list(self): + def main(n): + i = 0 + while i < n: + z = list(()) + z.append(1) + i += z[-1] / len(z) + return i + + log = self.run(main, [1000]) + assert log.result == main(1000) + loop, = log.loops_by_filename(self.filepath) + assert loop.match(""" + i7 = int_lt(i5, i6) + guard_true(i7, descr=...) + guard_not_invalidated(descr=...) + i9 = int_add(i5, 1) + --TICK-- + jump(..., descr=...) + """) + def test_floatlist_unpack_without_calls(self): def fn(n): l = [2.3, 3.4, 4.5] @@ -130,8 +131,7 @@ ops = loop.ops_by_id('look') assert 'call' not in log.opnames(ops) - #XXX the following tests only work with strategies enabled - + # XXX the following tests only work with strategies enabled def test_should_not_create_intobject_with_sets(self): def main(n): i = 0 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 @@ -48,3 +48,47 @@ i58 = arraylen_gc(p43, descr=...) jump(..., descr=...) """) + + def test_lock_acquire_release(self): + def main(n): + import threading + lock = threading.Lock() + while n > 0: + with lock: + n -= 1 + log = self.run(main, [500]) + assert log.result == main(500) + loop, = log.loops_by_filename(self.filepath) + assert loop.match(""" + i58 = int_gt(i43, 0) + guard_true(i58, descr=) + p59 = getfield_gc(p15, descr=) + i60 = getfield_gc(p59, descr=) + p61 = force_token() + setfield_gc(p0, p61, descr=) + i62 = call_release_gil(4312440032, i60, 1, descr=) + guard_not_forced(descr=) + guard_no_exception(descr=) + i63 = int_is_true(i62) + guard_true(i63, descr=) + i64 = int_sub(i43, 1) + guard_not_invalidated(descr=) + p66 = getfield_gc(p15, descr=) + i67 = getfield_gc(p66, descr=) + p68 = force_token() + setfield_gc(p0, p68, descr=) + i69 = call_release_gil(4312440032, i67, 0, descr=) + guard_not_forced(descr=) + guard_no_exception(descr=) + i70 = int_is_true(i69) + guard_false(i70, descr=) + i71 = getfield_gc(p66, descr=) + p72 = force_token() + setfield_gc(p0, p72, descr=) + call_release_gil(4312441056, i71, descr=) + guard_not_forced(descr=) + guard_no_exception(descr=) + guard_not_invalidated(descr=) + --TICK-- + jump(..., descr=TargetToken(4361239720)) + """) diff --git a/pypy/module/sys/test/test_sysmodule.py b/pypy/module/sys/test/test_sysmodule.py --- a/pypy/module/sys/test/test_sysmodule.py +++ b/pypy/module/sys/test/test_sysmodule.py @@ -704,7 +704,3 @@ except: assert g() is e test_call_in_subfunction.expected = 'n' - - -class AppTestSysExcInfoDirectCallMethod(AppTestSysExcInfoDirect): - spaceconfig = {"objspace.opcodes.CALL_METHOD": True} diff --git a/pypy/module/test_lib_pypy/cffi_tests/backend_tests.py b/pypy/module/test_lib_pypy/cffi_tests/backend_tests.py --- a/pypy/module/test_lib_pypy/cffi_tests/backend_tests.py +++ b/pypy/module/test_lib_pypy/cffi_tests/backend_tests.py @@ -199,6 +199,9 @@ typerepr = self.TypeRepr ffi = FFI(backend=self.Backend()) ffi.cdef("struct foo { short a, b, c; };") + p = ffi.cast("short unsigned int", 0) + assert repr(p) == "" + assert repr(ffi.typeof(p)) == typerepr % "unsigned short" p = ffi.cast("unsigned short int", 0) assert repr(p) == "" assert repr(ffi.typeof(p)) == typerepr % "unsigned short" @@ -535,13 +538,13 @@ for c_type, expected_size in [ ('char', 1), ('unsigned int', 4), - ('char *', SIZE_OF_LONG), + ('char *', SIZE_OF_PTR), ('int[5]', 20), ('struct foo', 12), ('union foo', 4), ]: size = ffi.sizeof(c_type) - assert size == expected_size + assert size == expected_size, (size, expected_size, ctype) def test_sizeof_cdata(self): ffi = FFI(backend=self.Backend()) diff --git a/pypy/module/test_lib_pypy/cffi_tests/callback_in_thread.py b/pypy/module/test_lib_pypy/cffi_tests/callback_in_thread.py --- a/pypy/module/test_lib_pypy/cffi_tests/callback_in_thread.py +++ b/pypy/module/test_lib_pypy/cffi_tests/callback_in_thread.py @@ -27,6 +27,7 @@ seen = [] @ffi.callback('int(*)(int,int)') def mycallback(x, y): + time.sleep(0.022) seen.append((x, y)) return 0 lib.threaded_ballback_test(mycallback) diff --git a/pypy/module/test_lib_pypy/cffi_tests/test_function.py b/pypy/module/test_lib_pypy/cffi_tests/test_function.py --- a/pypy/module/test_lib_pypy/cffi_tests/test_function.py +++ b/pypy/module/test_lib_pypy/cffi_tests/test_function.py @@ -382,3 +382,26 @@ sin100 = my_decorator(m.sin) x = sin100(1.23) assert x == math.sin(1.23) + 100 + + def test_free_callback_cycle(self): + if self.Backend is CTypesBackend: + py.test.skip("seems to fail with the ctypes backend on windows") + import weakref + def make_callback(data): + container = [data] + callback = ffi.callback('int()', lambda: len(container)) + container.append(callback) + # Ref cycle: callback -> lambda (closure) -> container -> callback + return callback + + class Data(object): + pass + ffi = FFI(backend=self.Backend()) + data = Data() + callback = make_callback(data) + wr = weakref.ref(data) + del callback, data + for i in range(3): + if wr() is not None: + import gc; gc.collect() + assert wr() is None # 'data' does not leak diff --git a/pypy/module/test_lib_pypy/cffi_tests/test_version.py b/pypy/module/test_lib_pypy/cffi_tests/test_version.py --- a/pypy/module/test_lib_pypy/cffi_tests/test_version.py +++ b/pypy/module/test_lib_pypy/cffi_tests/test_version.py @@ -8,6 +8,8 @@ BACKEND_VERSIONS = { '0.4.2': '0.4', # did not change + '0.7.1': '0.7', # did not change + '0.7.2': '0.7', # did not change } def test_version(): @@ -22,7 +24,7 @@ content = open(p).read() # v = cffi.__version__ - assert ("version = '%s'\n" % v) in content + assert ("version = '%s'\n" % BACKEND_VERSIONS.get(v, v)) in content assert ("release = '%s'\n" % v) in content def test_doc_version_file(): @@ -45,4 +47,5 @@ v = cffi.__version__ p = os.path.join(parent, 'c', 'test_c.py') content = open(p).read() - assert ('assert __version__ == "%s"' % v) in content + assert (('assert __version__ == "%s"' % BACKEND_VERSIONS.get(v, v)) + in content) diff --git a/pypy/module/test_lib_pypy/test_curses.py b/pypy/module/test_lib_pypy/test_curses.py --- a/pypy/module/test_lib_pypy/test_curses.py +++ b/pypy/module/test_lib_pypy/test_curses.py @@ -1,4 +1,8 @@ import pytest +import sys +if sys.platform == 'win32': + #This module does not exist in windows + pytest.skip('no curses on windows') # Check that lib_pypy.cffi finds the correct version of _cffi_backend. # Otherwise, the test is skipped. It should never be skipped when run From noreply at buildbot.pypy.org Tue Sep 10 00:30:37 2013 From: noreply at buildbot.pypy.org (pjenvey) Date: Tue, 10 Sep 2013 00:30:37 +0200 (CEST) Subject: [pypy-commit] pypy py3k: return a unicode name on py3 Message-ID: <20130909223037.28FCF1C1128@cobra.cs.uni-duesseldorf.de> Author: Philip Jenvey Branch: py3k Changeset: r66885:8b3000150d65 Date: 2013-09-09 14:26 -0700 http://bitbucket.org/pypy/pypy/changeset/8b3000150d65/ Log: return a unicode name on py3 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 @@ -496,7 +496,7 @@ name = w_self.name if name is None: name = '?' - return name + return name.decode('utf-8') def add_subclass(w_self, w_subclass): space = w_self.space From noreply at buildbot.pypy.org Tue Sep 10 00:30:38 2013 From: noreply at buildbot.pypy.org (pjenvey) Date: Tue, 10 Sep 2013 00:30:38 +0200 (CEST) Subject: [pypy-commit] pypy py3k: add py3 bytecodes Message-ID: <20130909223038.5A3221C1128@cobra.cs.uni-duesseldorf.de> Author: Philip Jenvey Branch: py3k Changeset: r66886:7c48f805ad02 Date: 2013-09-09 14:53 -0700 http://bitbucket.org/pypy/pypy/changeset/7c48f805ad02/ Log: add py3 bytecodes diff --git a/pypy/interpreter/pyopcode.py b/pypy/interpreter/pyopcode.py --- a/pypy/interpreter/pyopcode.py +++ b/pypy/interpreter/pyopcode.py @@ -219,8 +219,6 @@ self.BINARY_ADD(oparg, next_instr) elif opcode == opcodedesc.BINARY_AND.index: self.BINARY_AND(oparg, next_instr) - elif opcode == opcodedesc.BINARY_DIVIDE.index: - self.BINARY_DIVIDE(oparg, next_instr) elif opcode == opcodedesc.BINARY_FLOOR_DIVIDE.index: self.BINARY_FLOOR_DIVIDE(oparg, next_instr) elif opcode == opcodedesc.BINARY_LSHIFT.index: @@ -243,8 +241,6 @@ self.BINARY_TRUE_DIVIDE(oparg, next_instr) elif opcode == opcodedesc.BINARY_XOR.index: self.BINARY_XOR(oparg, next_instr) - elif opcode == opcodedesc.BUILD_CLASS.index: - self.BUILD_CLASS(oparg, next_instr) elif opcode == opcodedesc.BUILD_LIST.index: self.BUILD_LIST(oparg, next_instr) elif opcode == opcodedesc.BUILD_LIST_FROM_ARG.index: @@ -271,28 +267,20 @@ self.COMPARE_OP(oparg, next_instr) elif opcode == opcodedesc.DELETE_ATTR.index: self.DELETE_ATTR(oparg, next_instr) + elif opcode == opcodedesc.DELETE_DEREF.index: + self.DELETE_DEREF(oparg, next_instr) elif opcode == opcodedesc.DELETE_FAST.index: self.DELETE_FAST(oparg, next_instr) elif opcode == opcodedesc.DELETE_GLOBAL.index: self.DELETE_GLOBAL(oparg, next_instr) elif opcode == opcodedesc.DELETE_NAME.index: self.DELETE_NAME(oparg, next_instr) - elif opcode == opcodedesc.DELETE_SLICE_0.index: - self.DELETE_SLICE_0(oparg, next_instr) - elif opcode == opcodedesc.DELETE_SLICE_1.index: - self.DELETE_SLICE_1(oparg, next_instr) - elif opcode == opcodedesc.DELETE_SLICE_2.index: - self.DELETE_SLICE_2(oparg, next_instr) - elif opcode == opcodedesc.DELETE_SLICE_3.index: - self.DELETE_SLICE_3(oparg, next_instr) elif opcode == opcodedesc.DELETE_SUBSCR.index: self.DELETE_SUBSCR(oparg, next_instr) elif opcode == opcodedesc.DUP_TOP.index: self.DUP_TOP(oparg, next_instr) - elif opcode == opcodedesc.DUP_TOPX.index: - self.DUP_TOPX(oparg, next_instr) - elif opcode == opcodedesc.EXEC_STMT.index: - self.EXEC_STMT(oparg, next_instr) + elif opcode == opcodedesc.DUP_TOP_TWO.index: + self.DUP_TOP_TWO(oparg, next_instr) elif opcode == opcodedesc.GET_ITER.index: self.GET_ITER(oparg, next_instr) elif opcode == opcodedesc.IMPORT_FROM.index: @@ -305,8 +293,6 @@ self.INPLACE_ADD(oparg, next_instr) elif opcode == opcodedesc.INPLACE_AND.index: self.INPLACE_AND(oparg, next_instr) - elif opcode == opcodedesc.INPLACE_DIVIDE.index: - self.INPLACE_DIVIDE(oparg, next_instr) elif opcode == opcodedesc.INPLACE_FLOOR_DIVIDE.index: self.INPLACE_FLOOR_DIVIDE(oparg, next_instr) elif opcode == opcodedesc.INPLACE_LSHIFT.index: @@ -331,6 +317,8 @@ self.LIST_APPEND(oparg, next_instr) elif opcode == opcodedesc.LOAD_ATTR.index: self.LOAD_ATTR(oparg, next_instr) + elif opcode == opcodedesc.LOAD_BUILD_CLASS.index: + self.LOAD_BUILD_CLASS(oparg, next_instr) elif opcode == opcodedesc.LOAD_CLOSURE.index: self.LOAD_CLOSURE(oparg, next_instr) elif opcode == opcodedesc.LOAD_CONST.index: @@ -341,8 +329,6 @@ self.LOAD_FAST(oparg, next_instr) elif opcode == opcodedesc.LOAD_GLOBAL.index: self.LOAD_GLOBAL(oparg, next_instr) - elif opcode == opcodedesc.LOAD_LOCALS.index: - self.LOAD_LOCALS(oparg, next_instr) elif opcode == opcodedesc.LOAD_NAME.index: self.LOAD_NAME(oparg, next_instr) elif opcode == opcodedesc.LOOKUP_METHOD.index: @@ -357,22 +343,14 @@ self.NOP(oparg, next_instr) elif opcode == opcodedesc.POP_BLOCK.index: self.POP_BLOCK(oparg, next_instr) + elif opcode == opcodedesc.POP_EXCEPT.index: + self.POP_EXCEPT(oparg, next_instr) elif opcode == opcodedesc.POP_TOP.index: self.POP_TOP(oparg, next_instr) elif opcode == opcodedesc.PRINT_EXPR.index: self.PRINT_EXPR(oparg, next_instr) - elif opcode == opcodedesc.PRINT_ITEM.index: - self.PRINT_ITEM(oparg, next_instr) - elif opcode == opcodedesc.PRINT_ITEM_TO.index: - self.PRINT_ITEM_TO(oparg, next_instr) - elif opcode == opcodedesc.PRINT_NEWLINE.index: - self.PRINT_NEWLINE(oparg, next_instr) - elif opcode == opcodedesc.PRINT_NEWLINE_TO.index: - self.PRINT_NEWLINE_TO(oparg, next_instr) elif opcode == opcodedesc.RAISE_VARARGS.index: self.RAISE_VARARGS(oparg, next_instr) - elif opcode == opcodedesc.ROT_FOUR.index: - self.ROT_FOUR(oparg, next_instr) elif opcode == opcodedesc.ROT_THREE.index: self.ROT_THREE(oparg, next_instr) elif opcode == opcodedesc.ROT_TWO.index: @@ -387,14 +365,6 @@ self.SETUP_WITH(oparg, next_instr) elif opcode == opcodedesc.SET_ADD.index: self.SET_ADD(oparg, next_instr) - elif opcode == opcodedesc.SLICE_0.index: - self.SLICE_0(oparg, next_instr) - elif opcode == opcodedesc.SLICE_1.index: - self.SLICE_1(oparg, next_instr) - elif opcode == opcodedesc.SLICE_2.index: - self.SLICE_2(oparg, next_instr) - elif opcode == opcodedesc.SLICE_3.index: - self.SLICE_3(oparg, next_instr) elif opcode == opcodedesc.STOP_CODE.index: self.STOP_CODE(oparg, next_instr) elif opcode == opcodedesc.STORE_ATTR.index: @@ -405,22 +375,14 @@ self.STORE_FAST(oparg, next_instr) elif opcode == opcodedesc.STORE_GLOBAL.index: self.STORE_GLOBAL(oparg, next_instr) + elif opcode == opcodedesc.STORE_LOCALS.index: + self.STORE_LOCALS(oparg, next_instr) elif opcode == opcodedesc.STORE_MAP.index: self.STORE_MAP(oparg, next_instr) elif opcode == opcodedesc.STORE_NAME.index: self.STORE_NAME(oparg, next_instr) - elif opcode == opcodedesc.STORE_SLICE_0.index: - self.STORE_SLICE_0(oparg, next_instr) - elif opcode == opcodedesc.STORE_SLICE_1.index: - self.STORE_SLICE_1(oparg, next_instr) - elif opcode == opcodedesc.STORE_SLICE_2.index: - self.STORE_SLICE_2(oparg, next_instr) - elif opcode == opcodedesc.STORE_SLICE_3.index: - self.STORE_SLICE_3(oparg, next_instr) elif opcode == opcodedesc.STORE_SUBSCR.index: self.STORE_SUBSCR(oparg, next_instr) - elif opcode == opcodedesc.UNARY_CONVERT.index: - self.UNARY_CONVERT(oparg, next_instr) elif opcode == opcodedesc.UNARY_INVERT.index: self.UNARY_INVERT(oparg, next_instr) elif opcode == opcodedesc.UNARY_NEGATIVE.index: @@ -429,6 +391,8 @@ self.UNARY_NOT(oparg, next_instr) elif opcode == opcodedesc.UNARY_POSITIVE.index: self.UNARY_POSITIVE(oparg, next_instr) + elif opcode == opcodedesc.UNPACK_EX.index: + self.UNPACK_EX(oparg, next_instr) elif opcode == opcodedesc.UNPACK_SEQUENCE.index: self.UNPACK_SEQUENCE(oparg, next_instr) elif opcode == opcodedesc.WITH_CLEANUP.index: From noreply at buildbot.pypy.org Tue Sep 10 03:01:38 2013 From: noreply at buildbot.pypy.org (pjenvey) Date: Tue, 10 Sep 2013 03:01:38 +0200 (CEST) Subject: [pypy-commit] pypy py3k: translation fix Message-ID: <20130910010138.76F4A1C12EC@cobra.cs.uni-duesseldorf.de> Author: Philip Jenvey Branch: py3k Changeset: r66887:88b27fe9402e Date: 2013-09-09 18:00 -0700 http://bitbucket.org/pypy/pypy/changeset/88b27fe9402e/ Log: translation fix diff --git a/pypy/interpreter/baseobjspace.py b/pypy/interpreter/baseobjspace.py --- a/pypy/interpreter/baseobjspace.py +++ b/pypy/interpreter/baseobjspace.py @@ -82,7 +82,7 @@ return space.unicode_w(space.getattr(self, space.wrap('__name__'))) except OperationError, e: if e.match(space, space.w_TypeError) or e.match(space, space.w_AttributeError): - return '?' + return u'?' raise def getaddrstring(self, space): From noreply at buildbot.pypy.org Tue Sep 10 03:13:06 2013 From: noreply at buildbot.pypy.org (pjenvey) Date: Tue, 10 Sep 2013 03:13:06 +0200 (CEST) Subject: [pypy-commit] pypy py3k: oops Message-ID: <20130910011306.A2C351C026D@cobra.cs.uni-duesseldorf.de> Author: Philip Jenvey Branch: py3k Changeset: r66888:6cadba559578 Date: 2013-09-09 18:12 -0700 http://bitbucket.org/pypy/pypy/changeset/6cadba559578/ Log: oops 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 @@ -15,12 +15,7 @@ if not e.match(space, space.w_TypeError): raise else: - try: - classname = u'%s.%s' % (modulename, classname) - except: - try: from nose.tools import set_trace - except ImportError: from pdb import set_trace - set_trace() + classname = u'%s.%s' % (modulename, classname) return w_obj.getrepr(space, u'%s object' % (classname,)) def descr__str__(space, w_obj): From noreply at buildbot.pypy.org Tue Sep 10 09:46:57 2013 From: noreply at buildbot.pypy.org (arigo) Date: Tue, 10 Sep 2013 09:46:57 +0200 (CEST) Subject: [pypy-commit] pypy stmgc-c4: do_malloc_xx_clear(), used in the JIT Message-ID: <20130910074657.C80161C0175@cobra.cs.uni-duesseldorf.de> Author: Armin Rigo Branch: stmgc-c4 Changeset: r66889:0a12aff5926c Date: 2013-09-10 09:44 +0200 http://bitbucket.org/pypy/pypy/changeset/0a12aff5926c/ Log: do_malloc_xx_clear(), used in the JIT diff --git a/rpython/translator/stm/inevitable.py b/rpython/translator/stm/inevitable.py --- a/rpython/translator/stm/inevitable.py +++ b/rpython/translator/stm/inevitable.py @@ -29,7 +29,11 @@ GETTERS = set(['getfield', 'getarrayitem', 'getinteriorfield', 'raw_load']) SETTERS = set(['setfield', 'setarrayitem', 'setinteriorfield', 'raw_store']) MALLOCS = set(['malloc', 'malloc_varsize', - 'malloc_nonmovable', 'malloc_nonmovable_varsize']) + 'malloc_nonmovable', 'malloc_nonmovable_varsize', + 'raw_malloc', + 'do_malloc_fixedsize_clear', 'do_malloc_varsize_clear']) +FREES = set(['free', 'raw_free']) + # ____________________________________________________________ def should_turn_inevitable_getter_setter(op, fresh_mallocs): @@ -66,10 +70,8 @@ # # Mallocs & Frees if op.opname in MALLOCS: - # flags = op.args[1].value - # return flags['flavor'] != 'gc' - return False # XXX: Produces memory leaks on aborts - if op.opname == 'free': + return False + if op.opname in FREES: # We can only run a CFG in non-inevitable mode from start # to end in one transaction (every free gets called once # for every fresh malloc). No need to turn inevitable. @@ -77,12 +79,6 @@ # CFG will always run in inevitable mode anyways. return not fresh_mallocs.is_fresh_malloc(op.args[0]) # - if op.opname == 'raw_malloc': - return False # XXX: Produces memory leaks on aborts - if op.opname == 'raw_free': - return not fresh_mallocs.is_fresh_malloc(op.args[0]) - - # # Function calls if op.opname == 'direct_call': funcptr = op.args[0].value._obj diff --git a/rpython/translator/stm/test/test_inevitable.py b/rpython/translator/stm/test/test_inevitable.py --- a/rpython/translator/stm/test/test_inevitable.py +++ b/rpython/translator/stm/test/test_inevitable.py @@ -1,4 +1,5 @@ from rpython.rtyper.lltypesystem import lltype, llmemory, rffi +from rpython.rtyper.lltypesystem.lloperation import llop from rpython.rtyper.llinterp import LLFrame from rpython.rtyper.test import test_llinterp from rpython.rtyper.test.test_llinterp import get_interpreter, clear_tcache @@ -12,6 +13,12 @@ if self.llinterpreter.inevitable_cause is None: self.llinterpreter.inevitable_cause = info + def op_do_malloc_fixedsize_clear(self): + pass # just to check that it doesn't turn inevitable + + def op_do_malloc_varsize_clear(self): + pass # just to check that it doesn't turn inevitable + class TestTransform: @@ -239,3 +246,12 @@ res = self.interpret_inevitable(f, [2]) assert res == 'free' # not setfield or getfield + def test_do_malloc_llops(self): + def f(i): + # just to check that it doesn't turn inevitable + llop.do_malloc_fixedsize_clear(lltype.Void) + llop.do_malloc_varsize_clear(lltype.Void) + return i + + res = self.interpret_inevitable(f, [2]) + assert res is None From noreply at buildbot.pypy.org Tue Sep 10 11:12:30 2013 From: noreply at buildbot.pypy.org (arigo) Date: Tue, 10 Sep 2013 11:12:30 +0200 (CEST) Subject: [pypy-commit] pypy stmgc-c4: Disable stack-checking "more", with STM. In particular, avoid Message-ID: <20130910091230.0BD681C026D@cobra.cs.uni-duesseldorf.de> Author: Armin Rigo Branch: stmgc-c4 Changeset: r66890:5ea162371f3f Date: 2013-09-10 11:07 +0200 http://bitbucket.org/pypy/pypy/changeset/5ea162371f3f/ Log: Disable stack-checking "more", with STM. In particular, avoid calls to LL_stack_criticalcode_start(), turning the transaction inevitable. 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 @@ -182,6 +182,7 @@ STACK_CHECK_SLOWPATH = lltype.Ptr(lltype.FuncType([lltype.Signed], lltype.Void)) def insert_stack_check(): + assert not self.cpu.gc_ll_descr.stm endaddr = rstack._stack_get_end_adr() lengthaddr = rstack._stack_get_length_adr() f = llhelper(STACK_CHECK_SLOWPATH, rstack.stack_check_slowpath) 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 @@ -315,6 +315,8 @@ stmtlocal.tl_segment_prefix(mc) def _build_stack_check_slowpath(self): + if self.cpu.gc_ll_descr.stm: + return # XXX no stack check on STM for now _, _, slowpathaddr = self.cpu.insert_stack_check() if slowpathaddr == 0 or not self.cpu.propagate_exception_descr: return # no stack check (for tests, or non-translated) diff --git a/rpython/rlib/rstack.py b/rpython/rlib/rstack.py --- a/rpython/rlib/rstack.py +++ b/rpython/rlib/rstack.py @@ -23,6 +23,7 @@ def llexternal(name, args, res, _callable=None, **kwds): return rffi.llexternal(name, args, res, compilation_info=compilation_info, sandboxsafe=True, _nowrapper=True, + transactionsafe=True, _callable=_callable, **kwds) _stack_get_end = llexternal('LL_stack_get_end', [], lltype.Signed, @@ -34,24 +35,30 @@ lambda frac: None) _stack_too_big_slowpath = llexternal('LL_stack_too_big_slowpath', [lltype.Signed], lltype.Char, - lambda cur: '\x00', - transactionsafe=True) + lambda cur: '\x00') # the following is used by the JIT _stack_get_end_adr = llexternal('LL_stack_get_end_adr', [], lltype.Signed) _stack_get_length_adr= llexternal('LL_stack_get_length_adr',[], lltype.Signed) # the following is also used by the JIT: "critical code" paths are paths in # which we should not raise StackOverflow at all, but just ignore the stack limit -_stack_criticalcode_start = llexternal('LL_stack_criticalcode_start', [], - lltype.Void, lambda: None) -_stack_criticalcode_stop = llexternal('LL_stack_criticalcode_stop', [], - lltype.Void, lambda: None) +_LL_stack_criticalcode_start = llexternal('LL_stack_criticalcode_start', [], + lltype.Void) +_LL_stack_criticalcode_stop = llexternal('LL_stack_criticalcode_stop', [], + lltype.Void) +def _stack_criticalcode_start(): + if we_are_translated() and not rgc.stm_is_enabled(): + _LL_stack_criticalcode_start() +def _stack_criticalcode_stop(): + if we_are_translated() and not rgc.stm_is_enabled(): + _LL_stack_criticalcode_stop() + def stack_check(): if not we_are_translated(): return - # XXX --- custom version for STM --- - return # ignore + if rgc.stm_is_enabled(): + return # XXX ignore if we use STM # # Load the "current" stack position, or at least some address that # points close to the current stack head From noreply at buildbot.pypy.org Tue Sep 10 14:29:56 2013 From: noreply at buildbot.pypy.org (arigo) Date: Tue, 10 Sep 2013 14:29:56 +0200 (CEST) Subject: [pypy-commit] pypy default: Fix Message-ID: <20130910122956.ED4831C02A7@cobra.cs.uni-duesseldorf.de> Author: Armin Rigo Branch: Changeset: r66892:e23a1f3e941f Date: 2013-09-10 14:26 +0200 http://bitbucket.org/pypy/pypy/changeset/e23a1f3e941f/ Log: Fix diff --git a/rpython/rlib/rsre/rsre_re.py b/rpython/rlib/rsre/rsre_re.py --- a/rpython/rlib/rsre/rsre_re.py +++ b/rpython/rlib/rsre/rsre_re.py @@ -286,8 +286,8 @@ class Scanner: # This class is copied directly from re.py. def __init__(self, lexicon, flags=0): - from sre_constants import BRANCH, SUBPATTERN - import sre_parse + from rpython.rlib.rsre.rpy.sre_constants import BRANCH, SUBPATTERN + from rpython.rlib.rsre.rpy import sre_parse self.lexicon = lexicon # combine phrases into a compound pattern p = [] From noreply at buildbot.pypy.org Tue Sep 10 14:29:55 2013 From: noreply at buildbot.pypy.org (arigo) Date: Tue, 10 Sep 2013 14:29:55 +0200 (CEST) Subject: [pypy-commit] pypy default: Stop relying on the host stdlib's sre_*.py files, which can and do Message-ID: <20130910122955.C77F01C026D@cobra.cs.uni-duesseldorf.de> Author: Armin Rigo Branch: Changeset: r66891:7b0cafed5689 Date: 2013-09-10 14:22 +0200 http://bitbucket.org/pypy/pypy/changeset/7b0cafed5689/ Log: Stop relying on the host stdlib's sre_*.py files, which can and do change details (like in 2.7.4). Instead, copy directly the version we want to support (here 2.7.3) into the path rpython.rlib.rsre.rpy.sre_*. diff --git a/rpython/rlib/rsre/rpy/__init__.py b/rpython/rlib/rsre/rpy/__init__.py new file mode 100644 --- /dev/null +++ b/rpython/rlib/rsre/rpy/__init__.py @@ -0,0 +1,1 @@ +from ._sre import get_code diff --git a/rpython/rlib/rsre/rpy.py b/rpython/rlib/rsre/rpy/_sre.py rename from rpython/rlib/rsre/rpy.py rename to rpython/rlib/rsre/rpy/_sre.py --- a/rpython/rlib/rsre/rpy.py +++ b/rpython/rlib/rsre/rpy/_sre.py @@ -1,46 +1,24 @@ from rpython.rlib.rsre import rsre_char -from rpython.rlib.rsre.rsre_core import match from rpython.rlib.rarithmetic import intmask -def get_hacked_sre_compile(my_compile): - """Return a copy of the sre_compile module for which the _sre - module is a custom module that has _sre.compile == my_compile - and CODESIZE == rsre_char.CODESIZE. - """ - import sre_compile, sre_constants, __builtin__, new - sre_hacked = new.module("_sre_hacked") - sre_hacked.compile = my_compile - sre_hacked.MAGIC = sre_compile.MAGIC - sre_hacked.CODESIZE = rsre_char.CODESIZE - sre_hacked.MAXREPEAT = sre_constants.MAX_REPEAT - sre_hacked.getlower = rsre_char.getlower - def my_import(name, *args): - if name == '_sre': - return sre_hacked - else: - return default_import(name, *args) - src = sre_compile.__file__ - if src.lower().endswith('.pyc') or src.lower().endswith('.pyo'): - src = src[:-1] - mod = new.module("sre_compile_hacked") - default_import = __import__ - try: - __builtin__.__import__ = my_import - execfile(src, mod.__dict__) - finally: - __builtin__.__import__ = default_import - return mod + +MAGIC = 20031017 +CODESIZE = rsre_char.CODESIZE +getlower = rsre_char.getlower + class GotIt(Exception): pass -def my_compile(pattern, flags, code, *args): + +def compile(pattern, flags, code, *args): raise GotIt([intmask(i) for i in code], flags, args) -sre_compile_hacked = get_hacked_sre_compile(my_compile) + def get_code(regexp, flags=0, allargs=False): + from . import sre_compile try: - sre_compile_hacked.compile(regexp, flags) + sre_compile.compile(regexp, flags) except GotIt, e: pass else: diff --git a/lib-python/2.7/sre_compile.py b/rpython/rlib/rsre/rpy/sre_compile.py copy from lib-python/2.7/sre_compile.py copy to rpython/rlib/rsre/rpy/sre_compile.py --- a/lib-python/2.7/sre_compile.py +++ b/rpython/rlib/rsre/rpy/sre_compile.py @@ -8,11 +8,11 @@ # See the sre.py file for information on usage and redistribution. # -"""Internal support module for sre""" +"""Internal support module for sre (copied from CPython 2.7.3)""" -import _sre, sys -import sre_parse -from sre_constants import * +import sys +from . import _sre, sre_parse +from .sre_constants import * assert _sre.MAGIC == MAGIC, "SRE module mismatch" diff --git a/lib-python/2.7/sre_constants.py b/rpython/rlib/rsre/rpy/sre_constants.py copy from lib-python/2.7/sre_constants.py copy to rpython/rlib/rsre/rpy/sre_constants.py --- a/lib-python/2.7/sre_constants.py +++ b/rpython/rlib/rsre/rpy/sre_constants.py @@ -9,7 +9,7 @@ # See the sre.py file for information on usage and redistribution. # -"""Internal support module for sre""" +"""Internal support module for sre (copied from CPython 2.7.3)""" # update when constants are added or removed @@ -20,10 +20,8 @@ MAXREPEAT = 65535 # SRE standard exception (access as sre.error) -# should this really be here? - -class error(Exception): - pass +# (use the real re.error exception class) +from re import error # operators diff --git a/lib-python/2.7/sre_parse.py b/rpython/rlib/rsre/rpy/sre_parse.py copy from lib-python/2.7/sre_parse.py copy to rpython/rlib/rsre/rpy/sre_parse.py --- a/lib-python/2.7/sre_parse.py +++ b/rpython/rlib/rsre/rpy/sre_parse.py @@ -8,19 +8,13 @@ # See the sre.py file for information on usage and redistribution. # -"""Internal support module for sre""" +"""Internal support module for sre (copied from CPython 2.7.3)""" # XXX: show string offset and offending character for all errors import sys -from sre_constants import * - -try: - from __pypy__ import newdict -except ImportError: - assert '__pypy__' not in sys.builtin_module_names - newdict = lambda _ : {} +from .sre_constants import * SPECIAL_CHARS = ".\\[{()*+?^$|" REPEAT_CHARS = "*+?{" @@ -74,7 +68,7 @@ self.flags = 0 self.open = [] self.groups = 1 - self.groupdict = newdict("module") + self.groupdict = {} def opengroup(self, name=None): gid = self.groups self.groups = gid + 1 From noreply at buildbot.pypy.org Tue Sep 10 14:33:53 2013 From: noreply at buildbot.pypy.org (arigo) Date: Tue, 10 Sep 2013 14:33:53 +0200 (CEST) Subject: [pypy-commit] pypy default: Fix a last import Message-ID: <20130910123353.0E8731C026D@cobra.cs.uni-duesseldorf.de> Author: Armin Rigo Branch: Changeset: r66893:967ae258fa75 Date: 2013-09-10 14:33 +0200 http://bitbucket.org/pypy/pypy/changeset/967ae258fa75/ Log: Fix a last import diff --git a/rpython/rlib/rsre/test/test_char.py b/rpython/rlib/rsre/test/test_char.py --- a/rpython/rlib/rsre/test/test_char.py +++ b/rpython/rlib/rsre/test/test_char.py @@ -48,7 +48,7 @@ assert not rsre_char.is_uni_word(ord(',')) def test_category(): - from sre_constants import CHCODES + from rpython.rlib.rsre.rpy.sre_constants import CHCODES cat = rsre_char.category_dispatch # assert cat(CHCODES["category_digit"], ord('1')) From noreply at buildbot.pypy.org Tue Sep 10 22:34:16 2013 From: noreply at buildbot.pypy.org (arigo) Date: Tue, 10 Sep 2013 22:34:16 +0200 (CEST) Subject: [pypy-commit] pypy gc-del-2: Fixes Message-ID: <20130910203416.993A71C02B3@cobra.cs.uni-duesseldorf.de> Author: Armin Rigo Branch: gc-del-2 Changeset: r66894:aa0885f380b5 Date: 2013-09-10 22:16 +0200 http://bitbucket.org/pypy/pypy/changeset/aa0885f380b5/ Log: Fixes 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 @@ -682,8 +682,8 @@ def external_malloc(self, typeid, length): - """Allocate a large object using raw_malloc(), - possibly as an object with card marking enabled, + """Allocate a young, large object using raw_malloc(), possibly + as an object with card marking enabled, if large enough and if it has gc pointers in its var-sized part. 'length' should be specified as 0 if the object is not varsized. The returned object is fully initialized and zero-filled.""" @@ -738,12 +738,11 @@ extra_words = self.card_marking_words_for_length(length) cardheadersize = WORD * extra_words extra_flags = GCFLAG_HAS_CARDS | GCFLAG_TRACK_YOUNG_PTRS - # if 'can_make_young', then we also immediately set + # We also immediately set # GCFLAG_CARDS_SET, but without adding the object to # 'old_objects_with_cards_set'. In this way it should # never be added to that list as long as it is young. - if can_make_young: - extra_flags |= GCFLAG_CARDS_SET + extra_flags |= GCFLAG_CARDS_SET # # Detect very rare cases of overflows if raw_malloc_usage(totalsize) > (sys.maxint - (WORD-1) @@ -776,16 +775,12 @@ llarena.arena_reserve(result, totalsize) # # Record the newly allocated object and its full malloced size. - # The object is young or old depending on the argument. + # The new object is always young. self.rawmalloced_total_size += r_uint(allocsize) - if can_make_young: - if not self.young_objects_not_in_nursery: - self.young_objects_not_in_nursery = self.AddressDict() - self.young_objects_not_in_nursery.add(result + size_gc_header) - extra_flags |= GCFLAG_YOUNG_RAW_MALLOCED - else: - self.old_rawmalloced_objects.append(result + size_gc_header) - extra_flags |= GCFLAG_TRACK_YOUNG_PTRS + if not self.young_objects_not_in_nursery: + self.young_objects_not_in_nursery = self.AddressDict() + self.young_objects_not_in_nursery.add(result + size_gc_header) + extra_flags |= GCFLAG_YOUNG_RAW_MALLOCED # # Common code to fill the header and length of the object. self.init_gc_object(result, typeid, extra_flags) From noreply at buildbot.pypy.org Tue Sep 10 22:59:03 2013 From: noreply at buildbot.pypy.org (arigo) Date: Tue, 10 Sep 2013 22:59:03 +0200 (CEST) Subject: [pypy-commit] pypy default: issue 1595 Message-ID: <20130910205903.BD9011C02B3@cobra.cs.uni-duesseldorf.de> Author: Armin Rigo Branch: Changeset: r66895:7d4e13193892 Date: 2013-09-10 22:58 +0200 http://bitbucket.org/pypy/pypy/changeset/7d4e13193892/ Log: issue 1595 PyPy bug-to-bug compatibility with CPython 2.7. diff --git a/lib-python/2.7/argparse.py b/lib-python/2.7/argparse.py --- a/lib-python/2.7/argparse.py +++ b/lib-python/2.7/argparse.py @@ -1780,7 +1780,20 @@ # error if this argument is not allowed with other previously # seen arguments, assuming that actions that use the default # value don't really count as "present" - if argument_values is not action.default: + + # XXX PyPy bug-to-bug compatibility: "is" on primitive types + # is not consistent in CPython. We'll assume it is close + # enough for ints (which is true only for "small ints"), but + # for floats and longs and complexes and strings we'll go + # for the option of forcing "is" to say False, like it + # usually does on CPython. A fix is pending on CPython + # trunk (http://bugs.python.org/issue18943) but that might + # change the details of the semantics and so not be applied + # to 2.7. See the two lines AA below. + + if (argument_values is not action.default or + type(argument_values) in (float, long, complex, # AA + str, unicode)): # AA seen_non_default_actions.add(action) for conflict_action in action_conflicts.get(action, []): if conflict_action in seen_non_default_actions: From noreply at buildbot.pypy.org Tue Sep 10 23:08:58 2013 From: noreply at buildbot.pypy.org (arigo) Date: Tue, 10 Sep 2013 23:08:58 +0200 (CEST) Subject: [pypy-commit] pypy default: Don't use this logic for str and unicode. The other checks have been tested to not cause any CPython failure in test_argparse. Message-ID: <20130910210858.81F161C02B3@cobra.cs.uni-duesseldorf.de> Author: Armin Rigo Branch: Changeset: r66896:6fd3cdc48a70 Date: 2013-09-10 23:08 +0200 http://bitbucket.org/pypy/pypy/changeset/6fd3cdc48a70/ Log: Don't use this logic for str and unicode. The other checks have been tested to not cause any CPython failure in test_argparse. diff --git a/lib-python/2.7/argparse.py b/lib-python/2.7/argparse.py --- a/lib-python/2.7/argparse.py +++ b/lib-python/2.7/argparse.py @@ -1784,16 +1784,15 @@ # XXX PyPy bug-to-bug compatibility: "is" on primitive types # is not consistent in CPython. We'll assume it is close # enough for ints (which is true only for "small ints"), but - # for floats and longs and complexes and strings we'll go - # for the option of forcing "is" to say False, like it - # usually does on CPython. A fix is pending on CPython - # trunk (http://bugs.python.org/issue18943) but that might - # change the details of the semantics and so not be applied - # to 2.7. See the two lines AA below. + # for floats and longs and complexes we'll go for the option + # of forcing "is" to say False, like it usually does on + # CPython. A fix is pending on CPython trunk + # (http://bugs.python.org/issue18943) but that might change + # the details of the semantics and so not be applied to 2.7. + # See the line AA below. if (argument_values is not action.default or - type(argument_values) in (float, long, complex, # AA - str, unicode)): # AA + type(argument_values) in (float, long, complex)): # AA seen_non_default_actions.add(action) for conflict_action in action_conflicts.get(action, []): if conflict_action in seen_non_default_actions: From noreply at buildbot.pypy.org Wed Sep 11 01:31:14 2013 From: noreply at buildbot.pypy.org (wlav) Date: Wed, 11 Sep 2013 01:31:14 +0200 (CEST) Subject: [pypy-commit] pypy reflex-support: allow int(0) and None to be passed as NULL through instance* Message-ID: <20130910233114.3ADD21C0175@cobra.cs.uni-duesseldorf.de> Author: Wim Lavrijsen Branch: reflex-support Changeset: r66897:51089b1669b5 Date: 2013-09-10 15:55 -0700 http://bitbucket.org/pypy/pypy/changeset/51089b1669b5/ Log: allow int(0) and None to be passed as NULL through instance* 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 @@ -47,21 +47,22 @@ return rawobject return capi.C_NULL_OBJECT +def is_nullpointer_specialcase(space, w_obj): + # special case: allow integer 0 as (void*)0 + try: + return space.int_w(w_obj) == 0 + except Exception: + pass + # special case: allow None as (void*)0 + return space.is_true(space.is_(w_obj, space.w_None)) + def get_rawbuffer(space, w_obj): try: buf = space.buffer_w(w_obj) return rffi.cast(rffi.VOIDP, buf.get_raw_address()) except Exception: pass - # special case: allow integer 0 as NULL - try: - buf = space.int_w(w_obj) - if buf == 0: - return rffi.cast(rffi.VOIDP, 0) - except Exception: - pass - # special case: allow None as NULL - if space.is_true(space.is_(w_obj, space.w_None)): + if is_nullpointer_specialcase(space, w_obj): return rffi.cast(rffi.VOIDP, 0) raise TypeError("not an addressable buffer") @@ -412,7 +413,7 @@ _immutable_fields_ = ['uses_local'] uses_local = True -class InstancePtrConverter(TypeConverter): +class InstanceRefConverter(TypeConverter): _immutable_fields_ = ['libffitype', 'cppclass'] libffitype = jit_libffi.types.pointer @@ -444,17 +445,7 @@ x = rffi.cast(rffi.VOIDPP, address) x[0] = rffi.cast(rffi.VOIDP, self._unwrap_object(space, w_obj)) - def from_memory(self, space, w_obj, w_pycppclass, offset): - address = rffi.cast(capi.C_OBJECT, self._get_raw_address(space, w_obj, offset)) - from pypy.module.cppyy import interp_cppyy - return interp_cppyy.wrap_cppobject(space, address, self.cppclass, - do_cast=False, is_ref=True) - - def to_memory(self, space, w_obj, w_value, offset): - address = rffi.cast(rffi.VOIDPP, self._get_raw_address(space, w_obj, offset)) - address[0] = rffi.cast(rffi.VOIDP, self._unwrap_object(space, w_value)) - -class InstanceConverter(InstancePtrConverter): +class InstanceConverter(InstanceRefConverter): def convert_argument_libffi(self, space, w_obj, address, call_local): from pypy.module.cppyy.interp_cppyy import FastCallNotPossible @@ -468,6 +459,28 @@ def to_memory(self, space, w_obj, w_value, offset): self._is_abstract(space) + +class InstancePtrConverter(InstanceRefConverter): + + def _unwrap_object(self, space, w_obj): + try: + return InstanceRefConverter._unwrap_object(self, space, w_obj) + except OperationError, e: + # if not instance, allow certain special cases + if is_nullpointer_specialcase(space, w_obj): + return capi.C_NULL_OBJECT + raise e + + def from_memory(self, space, w_obj, w_pycppclass, offset): + address = rffi.cast(capi.C_OBJECT, self._get_raw_address(space, w_obj, offset)) + from pypy.module.cppyy import interp_cppyy + return interp_cppyy.wrap_cppobject(space, address, self.cppclass, + do_cast=False, is_ref=True) + + def to_memory(self, space, w_obj, w_value, offset): + address = rffi.cast(rffi.VOIDPP, self._get_raw_address(space, w_obj, offset)) + address[0] = rffi.cast(rffi.VOIDP, self._unwrap_object(space, w_value)) + class InstancePtrPtrConverter(InstancePtrConverter): _immutable_fields_ = ['uses_local'] @@ -487,12 +500,6 @@ from pypy.module.cppyy.interp_cppyy import FastCallNotPossible raise FastCallNotPossible - def from_memory(self, space, w_obj, w_pycppclass, offset): - self._is_abstract(space) - - def to_memory(self, space, w_obj, w_value, offset): - self._is_abstract(space) - def finalize_call(self, space, w_obj, call_local): from pypy.module.cppyy.interp_cppyy import W_CPPInstance assert isinstance(w_obj, W_CPPInstance) @@ -628,8 +635,10 @@ # 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 == "*" or compound == "&": + if compound == "*": return InstancePtrConverter(space, cppclass) + elif compound == "&": + return InstanceRefConverter(space, cppclass) elif compound == "**": return InstancePtrPtrConverter(space, cppclass) elif compound == "": 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 @@ -119,10 +119,12 @@ double* cppyy_test_data::get_double_array2() { return m_double_array2; } cppyy_test_pod cppyy_test_data::get_pod_val() { return m_pod; } -cppyy_test_pod* cppyy_test_data::get_pod_ptr() { return &m_pod; } -cppyy_test_pod& cppyy_test_data::get_pod_ref() { return m_pod; } +cppyy_test_pod* cppyy_test_data::get_pod_val_ptr() { return &m_pod; } +cppyy_test_pod& cppyy_test_data::get_pod_val_ref() { return m_pod; } cppyy_test_pod*& cppyy_test_data::get_pod_ptrref() { return m_ppod; } +cppyy_test_pod* cppyy_test_data::get_pod_ptr() { return m_ppod; } + //- setters ----------------------------------------------------------------- void cppyy_test_data::set_bool(bool b) { m_bool = b; } void cppyy_test_data::set_char(char c) { m_char = c; } @@ -159,6 +161,8 @@ void cppyy_test_data::set_pod_void_ptrptr_out(void** pp) { delete *((cppyy_test_pod**)pp); *((cppyy_test_pod**)pp) = new cppyy_test_pod(m_pod); } +void cppyy_test_data::set_pod_ptr(cppyy_test_pod* pp) { m_ppod = pp; } + //- passers ----------------------------------------------------------------- short* cppyy_test_data::pass_array(short* a) { return a; } unsigned short* cppyy_test_data::pass_array(unsigned short* a) { return a; } 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 @@ -89,11 +89,13 @@ double* get_double_array(); double* get_double_array2(); - cppyy_test_pod get_pod_val(); - cppyy_test_pod* get_pod_ptr(); - cppyy_test_pod& get_pod_ref(); + cppyy_test_pod get_pod_val(); // for m_pod + cppyy_test_pod* get_pod_val_ptr(); + cppyy_test_pod& get_pod_val_ref(); cppyy_test_pod*& get_pod_ptrref(); + cppyy_test_pod* get_pod_ptr(); // for m_ppod + // setters void set_bool(bool b); void set_char(char c); @@ -120,7 +122,7 @@ void set_double_c(const double& d); void set_enum(what w); - void set_pod_val(cppyy_test_pod); + void set_pod_val(cppyy_test_pod); // for m_pod void set_pod_ptr_in(cppyy_test_pod*); void set_pod_ptr_out(cppyy_test_pod*); void set_pod_ref(const cppyy_test_pod&); @@ -129,6 +131,8 @@ void set_pod_ptrptr_out(cppyy_test_pod**); void set_pod_void_ptrptr_out(void**); + void set_pod_ptr(cppyy_test_pod*); // for m_ppod + // passers short* pass_array(short*); unsigned short* pass_array(unsigned short*); 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 @@ -514,15 +514,15 @@ assert pod.m_int == 888 assert pod.m_double == 3.14 - assert c.get_pod_ptr().m_int == 888 - assert c.get_pod_ptr().m_double == 3.14 - c.get_pod_ptr().m_int = 777 - assert c.get_pod_ptr().m_int == 777 + assert c.get_pod_val_ptr().m_int == 888 + assert c.get_pod_val_ptr().m_double == 3.14 + c.get_pod_val_ptr().m_int = 777 + assert c.get_pod_val_ptr().m_int == 777 - assert c.get_pod_ref().m_int == 777 - assert c.get_pod_ref().m_double == 3.14 - c.get_pod_ref().m_int = 666 - assert c.get_pod_ref().m_int == 666 + assert c.get_pod_val_ref().m_int == 777 + assert c.get_pod_val_ref().m_double == 3.14 + c.get_pod_val_ref().m_int = 666 + assert c.get_pod_val_ref().m_int == 666 assert c.get_pod_ptrref().m_int == 666 assert c.get_pod_ptrref().m_double == 3.14 @@ -595,7 +595,22 @@ assert p.m_int == 888 assert p.m_double == 3.14 - def test16_respect_privacy(self): + def test16_nullptr_passing(self): + """Integer 0 ('NULL') and None allowed to pass through instance*""" + + import cppyy + + for o in (0, None): + c = cppyy.gbl.cppyy_test_data() + assert c.m_pod.m_int == 888 + assert c.m_pod.m_double == 3.14 + assert not not c.m_ppod + + c.set_pod_ptr(o) + assert not c.m_ppod + assert not c.get_pod_ptr() + + def test17_respect_privacy(self): """Test that privacy settings are respected""" import cppyy @@ -608,7 +623,7 @@ c.destruct() - def test17_object_and_pointer_comparisons(self): + def test18_object_and_pointer_comparisons(self): """Verify object and pointer comparisons""" import cppyy @@ -645,7 +660,7 @@ assert l3 != l5 assert l5 != l3 - def test18_object_validity(self): + def test19_object_validity(self): """Test object validity checking""" from cppyy import gbl @@ -659,7 +674,7 @@ assert not d2 - def test19_buffer_reshaping(self): + def test20_buffer_reshaping(self): """Test usage of buffer sizing""" import cppyy From noreply at buildbot.pypy.org Wed Sep 11 01:31:15 2013 From: noreply at buildbot.pypy.org (wlav) Date: Wed, 11 Sep 2013 01:31:15 +0200 (CEST) Subject: [pypy-commit] pypy reflex-support: code cleanup Message-ID: <20130910233115.6A56F1C0175@cobra.cs.uni-duesseldorf.de> Author: Wim Lavrijsen Branch: reflex-support Changeset: r66898:95801d352cc8 Date: 2013-09-10 16:00 -0700 http://bitbucket.org/pypy/pypy/changeset/95801d352cc8/ Log: code cleanup 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 @@ -262,8 +262,7 @@ self.name = name def convert_argument(self, space, w_obj, address, call_local): - raise OperationError(space.w_TypeError, - space.wrap('no converter available for type "%s"' % self.name)) + self._is_abstract(space) class BoolConverter(ffitypes.typeid(bool), TypeConverter): 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 @@ -190,7 +190,7 @@ assert "fragile::D::overload()" in str(e) assert "TypeError: wrong number of arguments" in str(e) assert "fragile::D::overload(fragile::no_such_class*)" in str(e) - assert "TypeError: no converter available for type \"fragile::no_such_class*\"" in str(e) + assert "TypeError: no converter available for 'fragile::no_such_class*'" in str(e) assert "fragile::D::overload(char, int)" in str(e) assert "TypeError: expected string, got NoneType object" in str(e) assert "fragile::D::overload(int, fragile::no_such_class*)" in str(e) From noreply at buildbot.pypy.org Wed Sep 11 03:54:37 2013 From: noreply at buildbot.pypy.org (rlamy) Date: Wed, 11 Sep 2013 03:54:37 +0200 (CEST) Subject: [pypy-commit] pypy less-stringly-ops: const() returns an instance of Constant Message-ID: <20130911015437.F34D11C073E@cobra.cs.uni-duesseldorf.de> Author: Ronan Lamy Branch: less-stringly-ops Changeset: r66899:f0d93e1cd108 Date: 2013-09-11 01:31 +0100 http://bitbucket.org/pypy/pypy/changeset/f0d93e1cd108/ Log: const() returns an instance of Constant Create ConstException which subclasses both Constant and FSException. This re-allows prebuilt Exception instances to appear in graphs. diff --git a/rpython/flowspace/model.py b/rpython/flowspace/model.py --- a/rpython/flowspace/model.py +++ b/rpython/flowspace/model.py @@ -355,6 +355,18 @@ def __str__(self): return '[%s: %s]' % (self.w_type, self.w_value) +class ConstException(Constant, FSException): + def foldable(self): + return True + + @property + def w_type(self): + return Constant(type(self.value)) + + @property + def w_value(self): + return Constant(self.value) + class UnwrapException(Exception): """Attempted to unwrap a Variable.""" @@ -378,7 +390,7 @@ if type(obj) is type_with_bad_introspection: raise WrapException elif isinstance(obj, Exception): - return FSException(Constant(type(obj)), Constant(obj)) + return ConstException(obj) return Constant(obj) class SpaceOperation(object): diff --git a/rpython/flowspace/test/test_objspace.py b/rpython/flowspace/test/test_objspace.py --- a/rpython/flowspace/test/test_objspace.py +++ b/rpython/flowspace/test/test_objspace.py @@ -3,7 +3,8 @@ import py from contextlib import contextmanager -from rpython.flowspace.model import Constant, mkentrymap, c_last_exception +from rpython.flowspace.model import ( + Constant, mkentrymap, c_last_exception, const) from rpython.translator.simplify import simplify_graph from rpython.flowspace.objspace import build_flow from rpython.flowspace.flowcontext import FlowingError, FlowSpaceFrame @@ -397,6 +398,18 @@ assert ops[0].opname == 'simple_call' assert ops[0].args == [Constant(ValueError), Constant('ouch')] + def test_raise_prebuilt(self): + error = ValueError('ouch') + def g(x): return x + def f(): + raise g(error) + x = self.codetest(f) + simplify_graph(x) + self.show(x) + ops = x.startblock.operations + assert ops[0].opname == 'simple_call' + assert ops[0].args == [const(g), const(error)] + #__________________________________________________________ def raise2(msg): raise IndexError, msg From noreply at buildbot.pypy.org Wed Sep 11 12:56:34 2013 From: noreply at buildbot.pypy.org (arigo) Date: Wed, 11 Sep 2013 12:56:34 +0200 (CEST) Subject: [pypy-commit] pypy default: Kill Message-ID: <20130911105634.BCF041C0175@cobra.cs.uni-duesseldorf.de> Author: Armin Rigo Branch: Changeset: r66900:4d752307b76b Date: 2013-09-11 12:55 +0200 http://bitbucket.org/pypy/pypy/changeset/4d752307b76b/ Log: Kill 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 @@ -166,9 +166,6 @@ 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, From noreply at buildbot.pypy.org Wed Sep 11 13:42:02 2013 From: noreply at buildbot.pypy.org (arigo) Date: Wed, 11 Sep 2013 13:42:02 +0200 (CEST) Subject: [pypy-commit] pypy gc-del-2: hg merge default Message-ID: <20130911114202.764101C0165@cobra.cs.uni-duesseldorf.de> Author: Armin Rigo Branch: gc-del-2 Changeset: r66901:f4a3255bc51e Date: 2013-09-11 13:40 +0200 http://bitbucket.org/pypy/pypy/changeset/f4a3255bc51e/ Log: hg merge default diff too long, truncating to 2000 out of 12437 lines diff --git a/dotviewer/graphparse.py b/dotviewer/graphparse.py --- a/dotviewer/graphparse.py +++ b/dotviewer/graphparse.py @@ -152,7 +152,8 @@ try: plaincontent = dot2plain_graphviz(content, contenttype) except PlainParseError, e: - print e - # failed, retry via codespeak - plaincontent = dot2plain_codespeak(content, contenttype) + raise + ##print e + ### failed, retry via codespeak + ##plaincontent = dot2plain_codespeak(content, contenttype) return list(parse_plain(graph_id, plaincontent, links, fixedfont)) diff --git a/lib-python/2.7/argparse.py b/lib-python/2.7/argparse.py --- a/lib-python/2.7/argparse.py +++ b/lib-python/2.7/argparse.py @@ -1780,7 +1780,19 @@ # error if this argument is not allowed with other previously # seen arguments, assuming that actions that use the default # value don't really count as "present" - if argument_values is not action.default: + + # XXX PyPy bug-to-bug compatibility: "is" on primitive types + # is not consistent in CPython. We'll assume it is close + # enough for ints (which is true only for "small ints"), but + # for floats and longs and complexes we'll go for the option + # of forcing "is" to say False, like it usually does on + # CPython. A fix is pending on CPython trunk + # (http://bugs.python.org/issue18943) but that might change + # the details of the semantics and so not be applied to 2.7. + # See the line AA below. + + if (argument_values is not action.default or + type(argument_values) in (float, long, complex)): # AA seen_non_default_actions.add(action) for conflict_action in action_conflicts.get(action, []): if conflict_action in seen_non_default_actions: diff --git a/lib-python/2.7/uuid.py b/lib-python/2.7/uuid.py --- a/lib-python/2.7/uuid.py +++ b/lib-python/2.7/uuid.py @@ -44,6 +44,8 @@ UUID('00010203-0405-0607-0809-0a0b0c0d0e0f') """ +import struct + __author__ = 'Ka-Ping Yee ' RESERVED_NCS, RFC_4122, RESERVED_MICROSOFT, RESERVED_FUTURE = [ @@ -125,25 +127,38 @@ overriding the given 'hex', 'bytes', 'bytes_le', 'fields', or 'int'. """ - if [hex, bytes, bytes_le, fields, int].count(None) != 4: - raise TypeError('need one of hex, bytes, bytes_le, fields, or int') if hex is not None: + if (bytes is not None or bytes_le is not None or fields is not None + or int is not None): + raise TypeError('if the hex argument is given, bytes, bytes_le, fields,' + ' and int need to be None') hex = hex.replace('urn:', '').replace('uuid:', '') hex = hex.strip('{}').replace('-', '') if len(hex) != 32: raise ValueError('badly formed hexadecimal UUID string') int = long(hex, 16) - if bytes_le is not None: + elif bytes_le is not None: + if bytes is not None or fields is not None or int is not None: + raise TypeError('if the bytes_le argument is given, bytes, fields,' + ' and int need to be None') if len(bytes_le) != 16: raise ValueError('bytes_le is not a 16-char string') bytes = (bytes_le[3] + bytes_le[2] + bytes_le[1] + bytes_le[0] + bytes_le[5] + bytes_le[4] + bytes_le[7] + bytes_le[6] + bytes_le[8:]) - if bytes is not None: + int = (struct.unpack('>Q', bytes[:8])[0] << 64 | + struct.unpack('>Q', bytes[8:])[0]) + elif bytes is not None: + if fields is not None or int is not None: + raise TypeError('if the bytes argument is given, fields' + ' and int need to be None') if len(bytes) != 16: raise ValueError('bytes is not a 16-char string') - int = long(('%02x'*16) % tuple(map(ord, bytes)), 16) - if fields is not None: + int = (struct.unpack('>Q', bytes[:8])[0] << 64 | + struct.unpack('>Q', bytes[8:])[0]) + elif fields is not None: + if int is not None: + raise TypeError('if the fields argument is given, int needs to be None') if len(fields) != 6: raise ValueError('fields is not a 6-tuple') (time_low, time_mid, time_hi_version, @@ -163,9 +178,12 @@ clock_seq = (clock_seq_hi_variant << 8L) | clock_seq_low int = ((time_low << 96L) | (time_mid << 80L) | (time_hi_version << 64L) | (clock_seq << 48L) | node) - if int is not None: + elif int is not None: if not 0 <= int < 1<<128L: raise ValueError('int is out of range (need a 128-bit value)') + else: + raise TypeError('one of hex, bytes, bytes_le, fields,' + ' or int need to be not None') if version is not None: if not 1 <= version <= 5: raise ValueError('illegal version number') @@ -175,7 +193,7 @@ # Set the version number. int &= ~(0xf000 << 64L) int |= version << 76L - self.__dict__['int'] = int + object.__setattr__(self, 'int', int) def __cmp__(self, other): if isinstance(other, UUID): diff --git a/lib_pypy/_curses.py b/lib_pypy/_curses.py --- a/lib_pypy/_curses.py +++ b/lib_pypy/_curses.py @@ -1,6 +1,9 @@ """Reimplementation of the standard extension module '_curses' using cffi.""" import sys +if sys.platform == 'win32': + #This module does not exist in windows + raise ImportError('No module named _curses') from functools import wraps from cffi import FFI diff --git a/lib_pypy/_sqlite3.py b/lib_pypy/_sqlite3.py --- a/lib_pypy/_sqlite3.py +++ b/lib_pypy/_sqlite3.py @@ -1229,7 +1229,10 @@ if cvt is not None: param = cvt(param) - param = adapt(param) + try: + param = adapt(param) + except: + pass # And use previous value if param is None: rc = _lib.sqlite3_bind_null(self._statement, idx) diff --git a/lib_pypy/_tkinter/__init__.py b/lib_pypy/_tkinter/__init__.py --- a/lib_pypy/_tkinter/__init__.py +++ b/lib_pypy/_tkinter/__init__.py @@ -22,6 +22,7 @@ READABLE = tklib.TCL_READABLE WRITABLE = tklib.TCL_WRITABLE EXCEPTION = tklib.TCL_EXCEPTION +DONT_WAIT = tklib.TCL_DONT_WAIT def create(screenName=None, baseName=None, className=None, interactive=False, wantobjects=False, wantTk=True, diff --git a/lib_pypy/_tkinter/app.py b/lib_pypy/_tkinter/app.py --- a/lib_pypy/_tkinter/app.py +++ b/lib_pypy/_tkinter/app.py @@ -4,7 +4,23 @@ from . import TclError from .tclobj import TclObject, FromObj, AsObj, TypeCache +import contextlib import sys +import threading +import time + + +class _DummyLock(object): + "A lock-like object that does not do anything" + def acquire(self): + pass + def release(self): + pass + def __enter__(self): + pass + def __exit__(self, *exc): + pass + def varname_converter(input): if isinstance(input, TclObject): @@ -37,17 +53,18 @@ def PythonCmd(clientData, interp, argc, argv): self = tkffi.from_handle(clientData) assert self.app.interp == interp - try: - args = [tkffi.string(arg) for arg in argv[1:argc]] - result = self.func(*args) - obj = AsObj(result) - tklib.Tcl_SetObjResult(interp, obj) - except: - self.app.errorInCmd = True - self.app.exc_info = sys.exc_info() - return tklib.TCL_ERROR - else: - return tklib.TCL_OK + with self.app._tcl_lock_released(): + try: + args = [tkffi.string(arg) for arg in argv[1:argc]] + result = self.func(*args) + obj = AsObj(result) + tklib.Tcl_SetObjResult(interp, obj) + except: + self.app.errorInCmd = True + self.app.exc_info = sys.exc_info() + return tklib.TCL_ERROR + else: + return tklib.TCL_OK @tkffi.callback("Tcl_CmdDeleteProc") def PythonCmdDelete(clientData): @@ -58,6 +75,8 @@ class TkApp(object): + _busywaitinterval = 0.02 # 20ms. + def __new__(cls, screenName, baseName, className, interactive, wantobjects, wantTk, sync, use): if not wantobjects: @@ -73,6 +92,12 @@ self.quitMainLoop = False self.errorInCmd = False + if not self.threaded: + # TCL is not thread-safe, calls needs to be serialized. + self._tcl_lock = threading.Lock() + else: + self._tcl_lock = _DummyLock() + self._typeCache = TypeCache() self._commands = {} @@ -133,6 +158,13 @@ if self.threaded and self.thread_id != tklib.Tcl_GetCurrentThread(): raise RuntimeError("Calling Tcl from different appartment") + @contextlib.contextmanager + def _tcl_lock_released(self): + "Context manager to temporarily release the tcl lock." + self._tcl_lock.release() + yield + self._tcl_lock.acquire() + def loadtk(self): # We want to guard against calling Tk_Init() multiple times err = tklib.Tcl_Eval(self.interp, "info exists tk_version") @@ -159,22 +191,25 @@ flags=tklib.TCL_LEAVE_ERR_MSG if global_only: flags |= tklib.TCL_GLOBAL_ONLY - res = tklib.Tcl_GetVar2Ex(self.interp, name1, name2, flags) - if not res: - self.raiseTclError() - assert self._wantobjects - return FromObj(self, res) + with self._tcl_lock: + res = tklib.Tcl_GetVar2Ex(self.interp, name1, name2, flags) + if not res: + self.raiseTclError() + assert self._wantobjects + return FromObj(self, res) def _setvar(self, name1, value, global_only=False): name1 = varname_converter(name1) + # XXX Acquire tcl lock??? newval = AsObj(value) flags=tklib.TCL_LEAVE_ERR_MSG if global_only: flags |= tklib.TCL_GLOBAL_ONLY - res = tklib.Tcl_SetVar2Ex(self.interp, name1, tkffi.NULL, - newval, flags) - if not res: - self.raiseTclError() + with self._tcl_lock: + res = tklib.Tcl_SetVar2Ex(self.interp, name1, tkffi.NULL, + newval, flags) + if not res: + self.raiseTclError() def _unsetvar(self, name1, name2=None, global_only=False): name1 = varname_converter(name1) @@ -183,9 +218,10 @@ flags=tklib.TCL_LEAVE_ERR_MSG if global_only: flags |= tklib.TCL_GLOBAL_ONLY - res = tklib.Tcl_UnsetVar2(self.interp, name1, name2, flags) - if res == tklib.TCL_ERROR: - self.raiseTclError() + with self._tcl_lock: + res = tklib.Tcl_UnsetVar2(self.interp, name1, name2, flags) + if res == tklib.TCL_ERROR: + self.raiseTclError() def getvar(self, name1, name2=None): return self._var_invoke(self._getvar, name1, name2) @@ -219,9 +255,10 @@ if self.threaded and self.thread_id != tklib.Tcl_GetCurrentThread(): raise NotImplementedError("Call from another thread") - res = tklib.Tcl_CreateCommand( - self.interp, cmdName, _CommandData.PythonCmd, - clientData, _CommandData.PythonCmdDelete) + with self._tcl_lock: + res = tklib.Tcl_CreateCommand( + self.interp, cmdName, _CommandData.PythonCmd, + clientData, _CommandData.PythonCmdDelete) if not res: raise TclError("can't create Tcl command") @@ -229,7 +266,8 @@ if self.threaded and self.thread_id != tklib.Tcl_GetCurrentThread(): raise NotImplementedError("Call from another thread") - res = tklib.Tcl_DeleteCommand(self.interp, cmdName) + with self._tcl_lock: + res = tklib.Tcl_DeleteCommand(self.interp, cmdName) if res == -1: raise TclError("can't delete Tcl command") @@ -256,11 +294,12 @@ tklib.Tcl_IncrRefCount(obj) objects[i] = obj - res = tklib.Tcl_EvalObjv(self.interp, argc, objects, flags) - if res == tklib.TCL_ERROR: - self.raiseTclError() - else: - result = self._callResult() + with self._tcl_lock: + res = tklib.Tcl_EvalObjv(self.interp, argc, objects, flags) + if res == tklib.TCL_ERROR: + self.raiseTclError() + else: + result = self._callResult() finally: for obj in objects: if obj: @@ -280,17 +319,19 @@ def eval(self, script): self._check_tcl_appartment() - res = tklib.Tcl_Eval(self.interp, script) - if res == tklib.TCL_ERROR: - self.raiseTclError() - return tkffi.string(tklib.Tcl_GetStringResult(self.interp)) + with self._tcl_lock: + res = tklib.Tcl_Eval(self.interp, script) + if res == tklib.TCL_ERROR: + self.raiseTclError() + return tkffi.string(tklib.Tcl_GetStringResult(self.interp)) def evalfile(self, filename): self._check_tcl_appartment() - res = tklib.Tcl_EvalFile(self.interp, filename) - if res == tklib.TCL_ERROR: - self.raiseTclError() - return tkffi.string(tklib.Tcl_GetStringResult(self.interp)) + with self._tcl_lock: + res = tklib.Tcl_EvalFile(self.interp, filename) + if res == tklib.TCL_ERROR: + self.raiseTclError() + return tkffi.string(tklib.Tcl_GetStringResult(self.interp)) def split(self, arg): if isinstance(arg, tuple): @@ -375,7 +416,10 @@ if self.threaded: result = tklib.Tcl_DoOneEvent(0) else: - raise NotImplementedError("TCL configured without threads") + with self._tcl_lock: + result = tklib.Tcl_DoOneEvent(tklib.TCL_DONT_WAIT) + if result == 0: + time.sleep(self._busywaitinterval) if result < 0: break diff --git a/lib_pypy/_tkinter/tklib.py b/lib_pypy/_tkinter/tklib.py --- a/lib_pypy/_tkinter/tklib.py +++ b/lib_pypy/_tkinter/tklib.py @@ -1,6 +1,7 @@ # C bindings with libtcl and libtk. from cffi import FFI +import sys tkffi = FFI() @@ -18,6 +19,8 @@ #define TCL_EVAL_DIRECT ... #define TCL_EVAL_GLOBAL ... +#define TCL_DONT_WAIT ... + typedef unsigned short Tcl_UniChar; typedef ... Tcl_Interp; typedef ...* Tcl_ThreadId; @@ -102,6 +105,17 @@ int Tk_GetNumMainWindows(); """) +# XXX find a better way to detect paths +# XXX pick up CPPFLAGS and LDFLAGS and add to these paths? +if sys.platform.startswith("openbsd"): + incdirs = ['/usr/local/include/tcl8.5', '/usr/local/include/tk8.5', '/usr/X11R6/include'] + linklibs = ['tk85', 'tcl85'] + libdirs = ['/usr/local/lib', '/usr/X11R6/lib'] +else: + incdirs=['/usr/include/tcl'] + linklibs=['tcl', 'tk'] + libdirs = [] + tklib = tkffi.verify(""" #include #include @@ -109,6 +123,7 @@ char *get_tk_version() { return TK_VERSION; } char *get_tcl_version() { return TCL_VERSION; } """, -include_dirs=['/usr/include/tcl'], -libraries=['tcl', 'tk'], +include_dirs=incdirs, +libraries=linklibs, +library_dirs = libdirs ) diff --git a/lib_pypy/cffi/__init__.py b/lib_pypy/cffi/__init__.py --- a/lib_pypy/cffi/__init__.py +++ b/lib_pypy/cffi/__init__.py @@ -4,5 +4,5 @@ from .api import FFI, CDefError, FFIError from .ffiplatform import VerificationError, VerificationMissing -__version__ = "0.7" -__version_info__ = (0, 7) +__version__ = "0.7.2" +__version_info__ = (0, 7, 2) diff --git a/lib_pypy/cffi/api.py b/lib_pypy/cffi/api.py --- a/lib_pypy/cffi/api.py +++ b/lib_pypy/cffi/api.py @@ -54,7 +54,8 @@ # _cffi_backend.so compiled. import _cffi_backend as backend from . import __version__ - assert backend.__version__ == __version__ + assert (backend.__version__ == __version__ or + backend.__version__ == __version__[:3]) # (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.) diff --git a/lib_pypy/cffi/commontypes.py b/lib_pypy/cffi/commontypes.py --- a/lib_pypy/cffi/commontypes.py +++ b/lib_pypy/cffi/commontypes.py @@ -30,7 +30,9 @@ elif result in model.PrimitiveType.ALL_PRIMITIVE_TYPES: result = model.PrimitiveType(result) else: - assert commontype != result + if commontype == result: + raise api.FFIError("Unsupported type: %r. Please file a bug " + "if you think it should be." % (commontype,)) result = resolve_common_type(result) # recursively assert isinstance(result, model.BaseTypeByIdentity) _CACHE[commontype] = result diff --git a/lib_pypy/cffi/cparser.py b/lib_pypy/cffi/cparser.py --- a/lib_pypy/cffi/cparser.py +++ b/lib_pypy/cffi/cparser.py @@ -290,13 +290,26 @@ # assume a primitive type. get it from .names, but reduce # synonyms to a single chosen combination names = list(type.names) - if names == ['signed'] or names == ['unsigned']: - names.append('int') - if names[0] == 'signed' and names != ['signed', 'char']: - names.pop(0) - if (len(names) > 1 and names[-1] == 'int' - and names != ['unsigned', 'int']): - names.pop() + if names != ['signed', 'char']: # keep this unmodified + prefixes = {} + while names: + name = names[0] + if name in ('short', 'long', 'signed', 'unsigned'): + prefixes[name] = prefixes.get(name, 0) + 1 + del names[0] + else: + break + # ignore the 'signed' prefix below, and reorder the others + newnames = [] + for prefix in ('unsigned', 'short', 'long'): + for i in range(prefixes.get(prefix, 0)): + newnames.append(prefix) + if not names: + names = ['int'] # implicitly + if names == ['int']: # but kill it if 'short' or 'long' + if 'short' in prefixes or 'long' in prefixes: + names = [] + names = newnames + names ident = ' '.join(names) if ident == 'void': return model.void_type @@ -500,8 +513,8 @@ self._partial_length = True return None # - raise api.FFIError("unsupported non-constant or " - "not immediately constant expression") + raise api.FFIError("unsupported expression: expected a " + "simple numeric constant") def _build_enum_type(self, explicit_name, decls): if decls is not None: diff --git a/lib_pypy/cffi/vengine_gen.py b/lib_pypy/cffi/vengine_gen.py --- a/lib_pypy/cffi/vengine_gen.py +++ b/lib_pypy/cffi/vengine_gen.py @@ -61,7 +61,9 @@ def load_library(self): # import it with the CFFI backend backend = self.ffi._backend - module = backend.load_library(self.verifier.modulefilename) + # needs to make a path that contains '/', on Posix + filename = os.path.join(os.curdir, self.verifier.modulefilename) + module = backend.load_library(filename) # # call loading_gen_struct() to get the struct layout inferred by # the C compiler diff --git a/lib_pypy/datetime.py b/lib_pypy/datetime.py --- a/lib_pypy/datetime.py +++ b/lib_pypy/datetime.py @@ -40,9 +40,9 @@ # for all computations. See the book for algorithms for converting between # proleptic Gregorian ordinals and many other calendar systems. -_DAYS_IN_MONTH = [None, 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31] +_DAYS_IN_MONTH = [-1, 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31] -_DAYS_BEFORE_MONTH = [None] +_DAYS_BEFORE_MONTH = [-1] dbm = 0 for dim in _DAYS_IN_MONTH[1:]: _DAYS_BEFORE_MONTH.append(dbm) diff --git a/pypy/config/pypyoption.py b/pypy/config/pypyoption.py --- a/pypy/config/pypyoption.py +++ b/pypy/config/pypyoption.py @@ -127,11 +127,6 @@ pypy_optiondescription = OptionDescription("objspace", "Object Space Options", [ - OptionDescription("opcodes", "opcodes to enable in the interpreter", [ - BoolOption("CALL_METHOD", "emit a special bytecode for expr.name()", - default=False), - ]), - OptionDescription("usemodules", "Which Modules should be used", [ BoolOption(modname, "use module %s" % (modname, ), default=modname in default_modules, @@ -259,9 +254,6 @@ BoolOption("optimized_int_add", "special case the addition of two integers in BINARY_ADD", default=False), - BoolOption("optimized_comparison_op", - "special case the comparison of integers", - default=False), BoolOption("optimized_list_getitem", "special case the 'list[integer]' expressions", default=False), @@ -307,7 +299,6 @@ # all the good optimizations for PyPy should be listed here if level in ['2', '3', 'jit']: - config.objspace.opcodes.suggest(CALL_METHOD=True) config.objspace.std.suggest(withrangelist=True) config.objspace.std.suggest(withmethodcache=True) config.objspace.std.suggest(withprebuiltchar=True) diff --git a/pypy/doc/coding-guide.rst b/pypy/doc/coding-guide.rst --- a/pypy/doc/coding-guide.rst +++ b/pypy/doc/coding-guide.rst @@ -339,9 +339,10 @@ + methods and other class attributes do not change after startup + single inheritance is fully supported -+ simple mixins somewhat work too, but the mixed in class needs a - ``_mixin_ = True`` class attribute. isinstance checks against the - mixin type will fail when translated. ++ use `rpython.rlib.objectmodel.import_from_mixin(M)` in a class + body to copy the whole content of a class `M`. This can be used + to implement mixins: functions and staticmethods are duplicated + (the other class attributes are just copied unmodified). + classes are first-class objects too diff --git a/pypy/doc/config/objspace.opcodes.CALL_METHOD.txt b/pypy/doc/config/objspace.opcodes.CALL_METHOD.txt deleted file mode 100644 --- a/pypy/doc/config/objspace.opcodes.CALL_METHOD.txt +++ /dev/null @@ -1,10 +0,0 @@ -Enable a pair of bytecodes that speed up method calls. -See ``pypy.interpreter.callmethod`` for a description. - -The goal is to avoid creating the bound method object in the common -case. So far, this only works for calls with no keyword, no ``*arg`` -and no ``**arg`` but it would be easy to extend. - -For more information, see the section in `Standard Interpreter Optimizations`_. - -.. _`Standard Interpreter Optimizations`: ../interpreter-optimizations.html#lookup-method-call-method diff --git a/pypy/doc/config/objspace.opcodes.txt b/pypy/doc/config/objspace.opcodes.txt deleted file mode 100644 --- a/pypy/doc/config/objspace.opcodes.txt +++ /dev/null @@ -1,1 +0,0 @@ -.. intentionally empty diff --git a/pypy/doc/cppyy.rst b/pypy/doc/cppyy.rst --- a/pypy/doc/cppyy.rst +++ b/pypy/doc/cppyy.rst @@ -83,7 +83,7 @@ the selection of scientific software) will also work for a build with the builtin backend. -.. _`download`: http://cern.ch/wlav/reflex-2013-04-23.tar.bz2 +.. _`download`: http://cern.ch/wlav/reflex-2013-08-14.tar.bz2 .. _`ROOT`: http://root.cern.ch/ Besides Reflex, you probably need a version of `gccxml`_ installed, which is @@ -98,8 +98,8 @@ To install the standalone version of Reflex, after download:: - $ tar jxf reflex-2013-04-23.tar.bz2 - $ cd reflex-2013-04-23 + $ tar jxf reflex-2013-08-14.tar.bz2 + $ cd reflex-2013-08-14 $ ./build/autogen $ ./configure $ make && make install 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 @@ -57,6 +57,12 @@ zlib-devel bzip2-devel ncurses-devel expat-devel \ openssl-devel gc-devel python-sphinx python-greenlet + On SLES11: + + $ sudo zypper install gcc make python-devel pkg-config \ + zlib-devel libopenssl-devel libbz2-devel sqlite3-devel \ + libexpat-devel libffi-devel python-curses + The above command lines are split with continuation characters, giving the necessary dependencies first, then the optional ones. * ``pkg-config`` (to help us locate libffi files) 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 @@ -198,9 +198,6 @@ if it is not None, then it is considered to be an additional first argument in the call to the *im_func* object from the stack. -You can enable this feature with the :config:`objspace.opcodes.CALL_METHOD` -option. - .. more here? Overall Effects diff --git a/pypy/doc/tool/makecontributor.py b/pypy/doc/tool/makecontributor.py --- a/pypy/doc/tool/makecontributor.py +++ b/pypy/doc/tool/makecontributor.py @@ -60,6 +60,11 @@ 'Roberto De Ioris': ['roberto at mrspurr'], 'Sven Hager': ['hager'], 'Tomo Cocoa': ['cocoatomo'], + 'Romain Guillebert': ['rguillebert', 'rguillbert', 'romain', 'Guillebert Romain'], + 'Ronan Lamy': ['ronan'], + 'Edd Barrett': ['edd'], + 'Manuel Jacob': ['mjacob'], + 'Rami Chowdhury': ['necaris'], } alias_map = {} @@ -80,7 +85,8 @@ if not match: return set() ignore_words = ['around', 'consulting', 'yesterday', 'for a bit', 'thanks', - 'in-progress', 'bits of', 'even a little', 'floating',] + 'in-progress', 'bits of', 'even a little', 'floating', + 'a bit', 'reviewing'] sep_words = ['and', ';', '+', '/', 'with special by'] nicknames = match.group(1) for word in ignore_words: @@ -119,7 +125,7 @@ ## print '%5d %s' % (n, name) ## else: ## print name - + items = authors_count.items() items.sort(key=operator.itemgetter(1), reverse=True) for name, n in items: 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 @@ -5,6 +5,11 @@ .. this is a revision shortly after release-2.1-beta .. startrev: 4eb52818e7c0 +.. branch: sanitise_bytecode_dispatch +Make PyPy's bytecode dispatcher easy to read, and less reliant on RPython +magic. There is no functional change, though the removal of dead code leads +to many fewer tests to execute. + .. branch: fastjson Fast json decoder written in RPython, about 3-4x faster than the pure Python decoder which comes with the stdlib @@ -74,3 +79,19 @@ .. branch: dotviewer-linewidth .. branch: reflex-support .. branch: numpypy-inplace-op +.. branch: rewritten-loop-logging +.. branch: no-release-gil + +.. branch: nobold-backtrace +Work on improving UnionError messages and stack trace displays. + +.. branch: improve-errors-again +More improvements and refactorings of error messages. + +.. branch: improve-errors-again2 +Unbreak tests in rlib. + +.. branch: less-stringly-ops +Use subclasses of SpaceOperation instead of SpaceOperator objects. +Random cleanups in flowspace. + diff --git a/pypy/doc/windows.rst b/pypy/doc/windows.rst --- a/pypy/doc/windows.rst +++ b/pypy/doc/windows.rst @@ -6,6 +6,10 @@ The following text gives some hints about how to translate the PyPy interpreter. +PyPy supports only being translated as a 32bit program, even on +64bit Windows. See at the end of this page for what is missing +for a full 64bit translation. + To build pypy-c you need a C compiler. Microsoft Visual Studio is preferred, but can also use the mingw32 port of gcc. @@ -63,7 +67,7 @@ INCLUDE, LIB and PATH (for DLLs) environment variables appropriately. Abridged method (for -Ojit builds using Visual Studio 2008) -~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ Download the versions of all the external packages from https://bitbucket.org/pypy/pypy/downloads/local.zip @@ -112,13 +116,14 @@ nmake -f makefile.msc The sqlite3 database library -~~~~~~~~~~~~~~~~~~~~ +~~~~~~~~~~~~~~~~~~~~~~~~~~~~ Download http://www.sqlite.org/2013/sqlite-amalgamation-3071601.zip and extract it into a directory under the base directory. Also get http://www.sqlite.org/2013/sqlite-dll-win32-x86-3071601.zip and extract the dll into the bin directory, and the sqlite3.def into the sources directory. Now build the import library so cffi can use the header and dll:: + lib /DEF:sqlite3.def" /OUT:sqlite3.lib" copy sqlite3.lib path\to\libs @@ -206,8 +211,86 @@ March 2012, --cc is not a valid option for pytest.py. However if you set an environment variable CC to the compliter exe, testing will use it. -.. _'mingw32 build': http://sourceforge.net/projects/mingw-w64/files/Toolchains%20targetting%20Win32/Automated%20Builds +.. _`mingw32 build`: http://sourceforge.net/projects/mingw-w64/files/Toolchains%20targetting%20Win32/Automated%20Builds .. _`mingw64 build`: http://sourceforge.net/projects/mingw-w64/files/Toolchains%20targetting%20Win64/Automated%20Builds .. _`msys for mingw`: http://sourceforge.net/projects/mingw-w64/files/External%20binary%20packages%20%28Win64%20hosted%29/MSYS%20%2832-bit%29 .. _`libffi source files`: http://sourceware.org/libffi/ .. _`RPython translation toolchain`: translation.html + + +What is missing for a full 64-bit translation +--------------------------------------------- + +The main blocker is that we assume that the integer type of RPython is +large enough to (occasionally) contain a pointer value cast to an +integer. The simplest fix is to make sure that it is so, but it will +give the following incompatibility between CPython and PyPy on Win64: + +CPython: ``sys.maxint == 2**32-1, sys.maxsize == 2**64-1`` + +PyPy: ``sys.maxint == sys.maxsize == 2**64-1`` + +...and, correspondingly, PyPy supports ints up to the larger value of +sys.maxint before they are converted to ``long``. The first decision +that someone needs to make is if this incompatibility is reasonable. + +Assuming that it is, the first thing to do is probably to hack *CPython* +until it fits this model: replace the field in PyIntObject with a ``long +long`` field, and change the value of ``sys.maxint``. This might just +work, even if half-brokenly: I'm sure you can crash it because of the +precision loss that undoubtedly occurs everywhere, but try not to. :-) + +Such a hacked CPython is what you'll use in the next steps. We'll call +it CPython64/64. + +It is probably not too much work if the goal is only to get a translated +PyPy executable, and to run all tests before transaction. But you need +to start somewhere, and you should start with some tests in +rpython/translator/c/test/, like ``test_standalone.py`` and +``test_newgc.py``: try to have them pass on top of CPython64/64. + +Keep in mind that this runs small translations, and some details may go +wrong. The most obvious one is to check that it produces C files that +use the integer type ``Signed`` --- but what is ``Signed`` defined to? +It should be equal to ``long`` on every other platforms, but on Win64 it +should be something like ``long long``. + +What is more generally needed is to review all the C files in +rpython/translator/c/src for the word ``long``, because this means a +32-bit integer even on Win64. Replace it with ``Signed`` most of the +times. You can replace one with the other without breaking anything on +any other platform, so feel free to. + +Then, these two C types have corresponding RPython types: ``rffi.LONG`` +and ``lltype.Signed`` respectively. The first should really correspond +to the C ``long``. Add tests that check that integers casted to one +type or the other really have 32 and 64 bits respectively, on Win64. + +Once these basic tests work, you need to review ``rpython/rlib/`` for +usages of ``rffi.LONG`` versus ``lltype.Signed``. The goal would be to +fix some more ``LONG-versus-Signed`` issues, by fixing the tests --- as +always run on top of CPython64/64. Note that there was some early work +done in ``rpython/rlib/rarithmetic`` with the goal of running all the +tests on Win64 on the regular CPython, but I think by now that it's a +bad idea. Look only at CPython64/64. + +The major intermediate goal is to get a translation of PyPy with ``-O2`` +with a minimal set of modules, starting with ``--no-allworkingmodules``; +you need to use CPython64/64 to run this translation too. Check +carefully the warnings of the C compiler at the end. I think that MSVC +is "nice" in the sense that by default a lot of mismatches of integer +sizes are reported as warnings. + +Then you need to review ``pypy/module/*/`` for ``LONG-versus-Signed`` +issues. At some time during this review, we get a working translated +PyPy on Windows 64 that includes all ``--translationmodules``, i.e. +everything needed to run translations. When we are there, the hacked +CPython64/64 becomes much less important, because we can run future +translations on top of this translated PyPy. As soon as we get there, +please *distribute* the translated PyPy. It's an essential component +for anyone else that wants to work on Win64! We end up with a strange +kind of dependency --- we need a translated PyPy in order to translate a +PyPy ---, but I believe it's ok here, as Windows executables are +supposed to never be broken by newer versions of Windows. + +Happy hacking :-) 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 @@ -119,13 +119,12 @@ except: try: stderr = sys.stderr - except AttributeError: - pass # too bad - else: print >> stderr, 'Error calling sys.excepthook:' originalexcepthook(*sys.exc_info()) print >> stderr print >> stderr, 'Original exception was:' + except: + pass # too bad # we only get here if sys.excepthook didn't do its job originalexcepthook(etype, evalue, etraceback) 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 @@ -982,9 +982,8 @@ return self._call_has_no_star_args(call) and not call.keywords def _optimize_method_call(self, call): - if not self.space.config.objspace.opcodes.CALL_METHOD or \ - not self._call_has_no_star_args(call) or \ - not isinstance(call.func, ast.Attribute): + if not self._call_has_no_star_args(call) or \ + not isinstance(call.func, ast.Attribute): return False attr_lookup = call.func assert isinstance(attr_lookup, ast.Attribute) diff --git a/pypy/interpreter/baseobjspace.py b/pypy/interpreter/baseobjspace.py --- a/pypy/interpreter/baseobjspace.py +++ b/pypy/interpreter/baseobjspace.py @@ -77,12 +77,12 @@ raise NotImplementedError("only for interp-level user subclasses " "from typedef.py") - def getname(self, space, default='?'): + def getname(self, space): try: return space.str_w(space.getattr(self, space.wrap('__name__'))) except OperationError, e: if e.match(space, space.w_TypeError) or e.match(space, space.w_AttributeError): - return default + return '?' raise def getaddrstring(self, space): diff --git a/pypy/interpreter/buffer.py b/pypy/interpreter/buffer.py --- a/pypy/interpreter/buffer.py +++ b/pypy/interpreter/buffer.py @@ -19,7 +19,7 @@ from pypy.interpreter.typedef import TypeDef from pypy.interpreter.gateway import interp2app, unwrap_spec from pypy.interpreter.error import OperationError -from rpython.rlib.objectmodel import compute_hash +from rpython.rlib.objectmodel import compute_hash, import_from_mixin from rpython.rlib.rstring import StringBuilder @@ -272,8 +272,6 @@ # ____________________________________________________________ class SubBufferMixin(object): - _mixin_ = True - def __init__(self, buffer, offset, size): self.buffer = buffer self.offset = offset @@ -297,10 +295,11 @@ # out of bounds return self.buffer.getslice(self.offset + start, self.offset + stop, step, size) -class SubBuffer(SubBufferMixin, Buffer): - pass +class SubBuffer(Buffer): + import_from_mixin(SubBufferMixin) -class RWSubBuffer(SubBufferMixin, RWBuffer): +class RWSubBuffer(RWBuffer): + import_from_mixin(SubBufferMixin) def setitem(self, index, char): self.buffer.setitem(self.offset + index, char) diff --git a/pypy/interpreter/function.py b/pypy/interpreter/function.py --- a/pypy/interpreter/function.py +++ b/pypy/interpreter/function.py @@ -482,17 +482,16 @@ space.abstract_isinstance_w(w_firstarg, self.w_class)): pass # ok else: - clsdescr = self.w_class.getname(space, "") - if clsdescr: + clsdescr = self.w_class.getname(space) + if clsdescr and clsdescr != '?': clsdescr += " instance" else: clsdescr = "instance" if w_firstarg is None: instdescr = "nothing" else: - instname = space.abstract_getclass(w_firstarg).getname(space, - "") - if instname: + instname = space.abstract_getclass(w_firstarg).getname(space) + if instname and instname != '?': instdescr = instname + " instance" else: instdescr = "instance" diff --git a/pypy/interpreter/pycode.py b/pypy/interpreter/pycode.py --- a/pypy/interpreter/pycode.py +++ b/pypy/interpreter/pycode.py @@ -251,8 +251,10 @@ tuple(self.co_cellvars)) def exec_host_bytecode(self, w_globals, w_locals): - from pypy.interpreter.pyframe import CPythonFrame - frame = CPythonFrame(self.space, self, w_globals, None) + if sys.version_info < (2, 7): + raise Exception("PyPy no longer supports Python 2.6 or lower") + from pypy.interpreter.pyframe import PyFrame + frame = self.space.FrameClass(self.space, self, w_globals, None) frame.setdictscope(w_locals) return frame.run() diff --git a/pypy/interpreter/pyframe.py b/pypy/interpreter/pyframe.py --- a/pypy/interpreter/pyframe.py +++ b/pypy/interpreter/pyframe.py @@ -52,7 +52,7 @@ def __init__(self, space, code, w_globals, outer_func): if not we_are_translated(): - assert type(self) in (space.FrameClass, CPythonFrame), ( + assert type(self) == space.FrameClass, ( "use space.FrameClass(), not directly PyFrame()") self = hint(self, access_directly=True, fresh_virtualizable=True) assert isinstance(code, pycode.PyCode) @@ -674,17 +674,6 @@ return space.wrap(self.builtin is not space.builtin) return space.w_False -class CPythonFrame(PyFrame): - """ - Execution of host (CPython) opcodes. - """ - - bytecode_spec = host_bytecode_spec - opcode_method_names = host_bytecode_spec.method_names - opcodedesc = host_bytecode_spec.opcodedesc - opdescmap = host_bytecode_spec.opdescmap - HAVE_ARGUMENT = host_bytecode_spec.HAVE_ARGUMENT - # ____________________________________________________________ diff --git a/pypy/interpreter/pyopcode.py b/pypy/interpreter/pyopcode.py --- a/pypy/interpreter/pyopcode.py +++ b/pypy/interpreter/pyopcode.py @@ -13,10 +13,8 @@ from rpython.rlib.objectmodel import we_are_translated from rpython.rlib import jit, rstackovf from rpython.rlib.rarithmetic import r_uint, intmask -from rpython.rlib.unroll import unrolling_iterable from rpython.rlib.debug import check_nonneg -from pypy.tool.stdlib_opcode import (bytecode_spec, - unrolling_all_opcode_descs) +from pypy.tool.stdlib_opcode import bytecode_spec def unaryoperation(operationname): """NOT_RPYTHON""" @@ -41,34 +39,14 @@ return func_with_new_name(opimpl, "opcode_impl_for_%s" % operationname) -compare_dispatch_table = [ - "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_dispatch_table)) - +opcodedesc = bytecode_spec.opcodedesc +HAVE_ARGUMENT = bytecode_spec.HAVE_ARGUMENT class __extend__(pyframe.PyFrame): """A PyFrame that knows about interpretation of standard Python opcodes minus the ones related to nested scopes.""" - bytecode_spec = bytecode_spec - opcode_method_names = bytecode_spec.method_names - opcodedesc = bytecode_spec.opcodedesc - opdescmap = bytecode_spec.opdescmap - HAVE_ARGUMENT = bytecode_spec.HAVE_ARGUMENT - ### opcode dispatch ### def dispatch(self, pycode, next_instr, ec): @@ -170,7 +148,7 @@ opcode = ord(co_code[next_instr]) next_instr += 1 - if opcode >= self.HAVE_ARGUMENT: + if opcode >= HAVE_ARGUMENT: lo = ord(co_code[next_instr]) hi = ord(co_code[next_instr+1]) next_instr += 2 @@ -180,19 +158,18 @@ # note: the structure of the code here is such that it makes # (after translation) a big "if/elif" chain, which is then - # turned into a switch(). It starts here: even if the first - # one is not an "if" but a "while" the effect is the same. + # turned into a switch(). - while opcode == self.opcodedesc.EXTENDED_ARG.index: + while opcode == opcodedesc.EXTENDED_ARG.index: opcode = ord(co_code[next_instr]) - if opcode < self.HAVE_ARGUMENT: + if opcode < HAVE_ARGUMENT: raise BytecodeCorruption lo = ord(co_code[next_instr+1]) hi = ord(co_code[next_instr+2]) next_instr += 3 oparg = (oparg * 65536) | (hi * 256) | lo - if opcode == self.opcodedesc.RETURN_VALUE.index: + if opcode == opcodedesc.RETURN_VALUE.index: w_returnvalue = self.popvalue() block = self.unrollstack(SReturnValue.kind) if block is None: @@ -202,8 +179,7 @@ unroller = SReturnValue(w_returnvalue) next_instr = block.handle(self, unroller) return next_instr # now inside a 'finally' block - - if opcode == self.opcodedesc.END_FINALLY.index: + elif opcode == opcodedesc.END_FINALLY.index: unroller = self.end_finally() if isinstance(unroller, SuspendedUnroller): # go on unrolling the stack @@ -215,49 +191,248 @@ else: next_instr = block.handle(self, unroller) return next_instr - - if opcode == self.opcodedesc.JUMP_ABSOLUTE.index: + elif opcode == opcodedesc.JUMP_ABSOLUTE.index: return self.jump_absolute(oparg, ec) - - if we_are_translated(): - for opdesc in unrolling_all_opcode_descs: - # static checks to skip this whole case if necessary - if opdesc.bytecode_spec is not self.bytecode_spec: - continue - if not opdesc.is_enabled(space): - continue - if opdesc.methodname in ( - 'EXTENDED_ARG', 'RETURN_VALUE', - 'END_FINALLY', 'JUMP_ABSOLUTE'): - continue # opcodes implemented above - - # the following "if" is part of the big switch described - # above. - if opcode == opdesc.index: - # dispatch to the opcode method - meth = getattr(self, opdesc.methodname) - res = meth(oparg, next_instr) - # !! warning, for the annotator the next line is not - # comparing an int and None - you can't do that. - # Instead, it's constant-folded to either True or False - if res is not None: - next_instr = res - break - else: - self.MISSING_OPCODE(oparg, next_instr) - - else: # when we are not translated, a list lookup is much faster - methodname = self.opcode_method_names[opcode] - try: - meth = getattr(self, methodname) - except AttributeError: - raise BytecodeCorruption("unimplemented opcode, ofs=%d, " - "code=%d, name=%s" % - (self.last_instr, opcode, - methodname)) - res = meth(oparg, next_instr) - if res is not None: - next_instr = res + elif opcode == opcodedesc.BREAK_LOOP.index: + next_instr = self.BREAK_LOOP(oparg, next_instr) + elif opcode == opcodedesc.CONTINUE_LOOP.index: + next_instr = self.CONTINUE_LOOP(oparg, next_instr) + elif opcode == opcodedesc.FOR_ITER.index: + next_instr = self.FOR_ITER(oparg, next_instr) + elif opcode == opcodedesc.JUMP_FORWARD.index: + next_instr = self.JUMP_FORWARD(oparg, next_instr) + elif opcode == opcodedesc.JUMP_IF_FALSE_OR_POP.index: + next_instr = self.JUMP_IF_FALSE_OR_POP(oparg, next_instr) + elif opcode == opcodedesc.JUMP_IF_NOT_DEBUG.index: + next_instr = self.JUMP_IF_NOT_DEBUG(oparg, next_instr) + elif opcode == opcodedesc.JUMP_IF_TRUE_OR_POP.index: + next_instr = self.JUMP_IF_TRUE_OR_POP(oparg, next_instr) + elif opcode == opcodedesc.POP_JUMP_IF_FALSE.index: + next_instr = self.POP_JUMP_IF_FALSE(oparg, next_instr) + elif opcode == opcodedesc.POP_JUMP_IF_TRUE.index: + next_instr = self.POP_JUMP_IF_TRUE(oparg, next_instr) + elif opcode == opcodedesc.BINARY_ADD.index: + self.BINARY_ADD(oparg, next_instr) + elif opcode == opcodedesc.BINARY_AND.index: + self.BINARY_AND(oparg, next_instr) + elif opcode == opcodedesc.BINARY_DIVIDE.index: + self.BINARY_DIVIDE(oparg, next_instr) + elif opcode == opcodedesc.BINARY_FLOOR_DIVIDE.index: + self.BINARY_FLOOR_DIVIDE(oparg, next_instr) + elif opcode == opcodedesc.BINARY_LSHIFT.index: + self.BINARY_LSHIFT(oparg, next_instr) + elif opcode == opcodedesc.BINARY_MODULO.index: + self.BINARY_MODULO(oparg, next_instr) + elif opcode == opcodedesc.BINARY_MULTIPLY.index: + self.BINARY_MULTIPLY(oparg, next_instr) + elif opcode == opcodedesc.BINARY_OR.index: + self.BINARY_OR(oparg, next_instr) + elif opcode == opcodedesc.BINARY_POWER.index: + self.BINARY_POWER(oparg, next_instr) + elif opcode == opcodedesc.BINARY_RSHIFT.index: + self.BINARY_RSHIFT(oparg, next_instr) + elif opcode == opcodedesc.BINARY_SUBSCR.index: + self.BINARY_SUBSCR(oparg, next_instr) + elif opcode == opcodedesc.BINARY_SUBTRACT.index: + self.BINARY_SUBTRACT(oparg, next_instr) + elif opcode == opcodedesc.BINARY_TRUE_DIVIDE.index: + self.BINARY_TRUE_DIVIDE(oparg, next_instr) + elif opcode == opcodedesc.BINARY_XOR.index: + self.BINARY_XOR(oparg, next_instr) + elif opcode == opcodedesc.BUILD_CLASS.index: + self.BUILD_CLASS(oparg, next_instr) + elif opcode == opcodedesc.BUILD_LIST.index: + self.BUILD_LIST(oparg, next_instr) + elif opcode == opcodedesc.BUILD_LIST_FROM_ARG.index: + self.BUILD_LIST_FROM_ARG(oparg, next_instr) + elif opcode == opcodedesc.BUILD_MAP.index: + self.BUILD_MAP(oparg, next_instr) + elif opcode == opcodedesc.BUILD_SET.index: + self.BUILD_SET(oparg, next_instr) + elif opcode == opcodedesc.BUILD_SLICE.index: + self.BUILD_SLICE(oparg, next_instr) + elif opcode == opcodedesc.BUILD_TUPLE.index: + self.BUILD_TUPLE(oparg, next_instr) + elif opcode == opcodedesc.CALL_FUNCTION.index: + self.CALL_FUNCTION(oparg, next_instr) + elif opcode == opcodedesc.CALL_FUNCTION_KW.index: + self.CALL_FUNCTION_KW(oparg, next_instr) + elif opcode == opcodedesc.CALL_FUNCTION_VAR.index: + self.CALL_FUNCTION_VAR(oparg, next_instr) + elif opcode == opcodedesc.CALL_FUNCTION_VAR_KW.index: + self.CALL_FUNCTION_VAR_KW(oparg, next_instr) + elif opcode == opcodedesc.CALL_METHOD.index: + self.CALL_METHOD(oparg, next_instr) + elif opcode == opcodedesc.COMPARE_OP.index: + self.COMPARE_OP(oparg, next_instr) + elif opcode == opcodedesc.DELETE_ATTR.index: + self.DELETE_ATTR(oparg, next_instr) + elif opcode == opcodedesc.DELETE_FAST.index: + self.DELETE_FAST(oparg, next_instr) + elif opcode == opcodedesc.DELETE_GLOBAL.index: + self.DELETE_GLOBAL(oparg, next_instr) + elif opcode == opcodedesc.DELETE_NAME.index: + self.DELETE_NAME(oparg, next_instr) + elif opcode == opcodedesc.DELETE_SLICE_0.index: + self.DELETE_SLICE_0(oparg, next_instr) + elif opcode == opcodedesc.DELETE_SLICE_1.index: + self.DELETE_SLICE_1(oparg, next_instr) + elif opcode == opcodedesc.DELETE_SLICE_2.index: + self.DELETE_SLICE_2(oparg, next_instr) + elif opcode == opcodedesc.DELETE_SLICE_3.index: + self.DELETE_SLICE_3(oparg, next_instr) + elif opcode == opcodedesc.DELETE_SUBSCR.index: + self.DELETE_SUBSCR(oparg, next_instr) + elif opcode == opcodedesc.DUP_TOP.index: + self.DUP_TOP(oparg, next_instr) + elif opcode == opcodedesc.DUP_TOPX.index: + self.DUP_TOPX(oparg, next_instr) + elif opcode == opcodedesc.EXEC_STMT.index: + self.EXEC_STMT(oparg, next_instr) + elif opcode == opcodedesc.GET_ITER.index: + self.GET_ITER(oparg, next_instr) + elif opcode == opcodedesc.IMPORT_FROM.index: + self.IMPORT_FROM(oparg, next_instr) + elif opcode == opcodedesc.IMPORT_NAME.index: + self.IMPORT_NAME(oparg, next_instr) + elif opcode == opcodedesc.IMPORT_STAR.index: + self.IMPORT_STAR(oparg, next_instr) + elif opcode == opcodedesc.INPLACE_ADD.index: + self.INPLACE_ADD(oparg, next_instr) + elif opcode == opcodedesc.INPLACE_AND.index: + self.INPLACE_AND(oparg, next_instr) + elif opcode == opcodedesc.INPLACE_DIVIDE.index: + self.INPLACE_DIVIDE(oparg, next_instr) + elif opcode == opcodedesc.INPLACE_FLOOR_DIVIDE.index: + self.INPLACE_FLOOR_DIVIDE(oparg, next_instr) + elif opcode == opcodedesc.INPLACE_LSHIFT.index: + self.INPLACE_LSHIFT(oparg, next_instr) + elif opcode == opcodedesc.INPLACE_MODULO.index: + self.INPLACE_MODULO(oparg, next_instr) + elif opcode == opcodedesc.INPLACE_MULTIPLY.index: + self.INPLACE_MULTIPLY(oparg, next_instr) + elif opcode == opcodedesc.INPLACE_OR.index: + self.INPLACE_OR(oparg, next_instr) + elif opcode == opcodedesc.INPLACE_POWER.index: + self.INPLACE_POWER(oparg, next_instr) + elif opcode == opcodedesc.INPLACE_RSHIFT.index: + self.INPLACE_RSHIFT(oparg, next_instr) + elif opcode == opcodedesc.INPLACE_SUBTRACT.index: + self.INPLACE_SUBTRACT(oparg, next_instr) + elif opcode == opcodedesc.INPLACE_TRUE_DIVIDE.index: + self.INPLACE_TRUE_DIVIDE(oparg, next_instr) + elif opcode == opcodedesc.INPLACE_XOR.index: + self.INPLACE_XOR(oparg, next_instr) + elif opcode == opcodedesc.LIST_APPEND.index: + self.LIST_APPEND(oparg, next_instr) + elif opcode == opcodedesc.LOAD_ATTR.index: + self.LOAD_ATTR(oparg, next_instr) + elif opcode == opcodedesc.LOAD_CLOSURE.index: + self.LOAD_CLOSURE(oparg, next_instr) + elif opcode == opcodedesc.LOAD_CONST.index: + self.LOAD_CONST(oparg, next_instr) + elif opcode == opcodedesc.LOAD_DEREF.index: + self.LOAD_DEREF(oparg, next_instr) + elif opcode == opcodedesc.LOAD_FAST.index: + self.LOAD_FAST(oparg, next_instr) + elif opcode == opcodedesc.LOAD_GLOBAL.index: + self.LOAD_GLOBAL(oparg, next_instr) + elif opcode == opcodedesc.LOAD_LOCALS.index: + self.LOAD_LOCALS(oparg, next_instr) + elif opcode == opcodedesc.LOAD_NAME.index: + self.LOAD_NAME(oparg, next_instr) + elif opcode == opcodedesc.LOOKUP_METHOD.index: + self.LOOKUP_METHOD(oparg, next_instr) + elif opcode == opcodedesc.MAKE_CLOSURE.index: + self.MAKE_CLOSURE(oparg, next_instr) + elif opcode == opcodedesc.MAKE_FUNCTION.index: + self.MAKE_FUNCTION(oparg, next_instr) + elif opcode == opcodedesc.MAP_ADD.index: + self.MAP_ADD(oparg, next_instr) + elif opcode == opcodedesc.NOP.index: + self.NOP(oparg, next_instr) + elif opcode == opcodedesc.POP_BLOCK.index: + self.POP_BLOCK(oparg, next_instr) + elif opcode == opcodedesc.POP_TOP.index: + self.POP_TOP(oparg, next_instr) + elif opcode == opcodedesc.PRINT_EXPR.index: + self.PRINT_EXPR(oparg, next_instr) + elif opcode == opcodedesc.PRINT_ITEM.index: + self.PRINT_ITEM(oparg, next_instr) + elif opcode == opcodedesc.PRINT_ITEM_TO.index: + self.PRINT_ITEM_TO(oparg, next_instr) + elif opcode == opcodedesc.PRINT_NEWLINE.index: + self.PRINT_NEWLINE(oparg, next_instr) + elif opcode == opcodedesc.PRINT_NEWLINE_TO.index: + self.PRINT_NEWLINE_TO(oparg, next_instr) + elif opcode == opcodedesc.RAISE_VARARGS.index: + self.RAISE_VARARGS(oparg, next_instr) + elif opcode == opcodedesc.ROT_FOUR.index: + self.ROT_FOUR(oparg, next_instr) + elif opcode == opcodedesc.ROT_THREE.index: + self.ROT_THREE(oparg, next_instr) + elif opcode == opcodedesc.ROT_TWO.index: + self.ROT_TWO(oparg, next_instr) + elif opcode == opcodedesc.SETUP_EXCEPT.index: + self.SETUP_EXCEPT(oparg, next_instr) + elif opcode == opcodedesc.SETUP_FINALLY.index: + self.SETUP_FINALLY(oparg, next_instr) + elif opcode == opcodedesc.SETUP_LOOP.index: + self.SETUP_LOOP(oparg, next_instr) + elif opcode == opcodedesc.SETUP_WITH.index: + self.SETUP_WITH(oparg, next_instr) + elif opcode == opcodedesc.SET_ADD.index: + self.SET_ADD(oparg, next_instr) + elif opcode == opcodedesc.SLICE_0.index: + self.SLICE_0(oparg, next_instr) + elif opcode == opcodedesc.SLICE_1.index: + self.SLICE_1(oparg, next_instr) + elif opcode == opcodedesc.SLICE_2.index: + self.SLICE_2(oparg, next_instr) + elif opcode == opcodedesc.SLICE_3.index: + self.SLICE_3(oparg, next_instr) + elif opcode == opcodedesc.STOP_CODE.index: + self.STOP_CODE(oparg, next_instr) + elif opcode == opcodedesc.STORE_ATTR.index: + self.STORE_ATTR(oparg, next_instr) + elif opcode == opcodedesc.STORE_DEREF.index: + self.STORE_DEREF(oparg, next_instr) + elif opcode == opcodedesc.STORE_FAST.index: + self.STORE_FAST(oparg, next_instr) + elif opcode == opcodedesc.STORE_GLOBAL.index: + self.STORE_GLOBAL(oparg, next_instr) + elif opcode == opcodedesc.STORE_MAP.index: + self.STORE_MAP(oparg, next_instr) + elif opcode == opcodedesc.STORE_NAME.index: + self.STORE_NAME(oparg, next_instr) + elif opcode == opcodedesc.STORE_SLICE_0.index: + self.STORE_SLICE_0(oparg, next_instr) + elif opcode == opcodedesc.STORE_SLICE_1.index: + self.STORE_SLICE_1(oparg, next_instr) + elif opcode == opcodedesc.STORE_SLICE_2.index: + self.STORE_SLICE_2(oparg, next_instr) + elif opcode == opcodedesc.STORE_SLICE_3.index: + self.STORE_SLICE_3(oparg, next_instr) + elif opcode == opcodedesc.STORE_SUBSCR.index: + self.STORE_SUBSCR(oparg, next_instr) + elif opcode == opcodedesc.UNARY_CONVERT.index: + self.UNARY_CONVERT(oparg, next_instr) + elif opcode == opcodedesc.UNARY_INVERT.index: + self.UNARY_INVERT(oparg, next_instr) + elif opcode == opcodedesc.UNARY_NEGATIVE.index: + self.UNARY_NEGATIVE(oparg, next_instr) + elif opcode == opcodedesc.UNARY_NOT.index: + self.UNARY_NOT(oparg, next_instr) + elif opcode == opcodedesc.UNARY_POSITIVE.index: + self.UNARY_POSITIVE(oparg, next_instr) + elif opcode == opcodedesc.UNPACK_SEQUENCE.index: + self.UNPACK_SEQUENCE(oparg, next_instr) + elif opcode == opcodedesc.WITH_CLEANUP.index: + self.WITH_CLEANUP(oparg, next_instr) + elif opcode == opcodedesc.YIELD_VALUE.index: + self.YIELD_VALUE(oparg, next_instr) + else: + self.MISSING_OPCODE(oparg, next_instr) if jit.we_are_jitted(): return next_instr @@ -733,36 +908,6 @@ self.pushvalue(w_value) LOAD_ATTR._always_inline_ = True - def cmp_lt(self, w_1, w_2): - return self.space.lt(w_1, w_2) - - def cmp_le(self, w_1, w_2): - return self.space.le(w_1, w_2) - - def cmp_eq(self, w_1, w_2): - return self.space.eq(w_1, w_2) - - def cmp_ne(self, w_1, w_2): - return self.space.ne(w_1, w_2) - - def cmp_gt(self, w_1, w_2): - return self.space.gt(w_1, w_2) - - def cmp_ge(self, w_1, w_2): - return self.space.ge(w_1, w_2) - - def cmp_in(self, w_1, w_2): - return self.space.contains(w_2, w_1) - - def cmp_not_in(self, w_1, w_2): - return self.space.not_(self.space.contains(w_2, w_1)) - - def cmp_is(self, w_1, w_2): - return self.space.is_(w_1, w_2) - - def cmp_is_not(self, w_1, w_2): - return self.space.not_(self.space.is_(w_1, w_2)) - @jit.unroll_safe def cmp_exc_match(self, w_1, w_2): space = self.space @@ -779,11 +924,28 @@ def COMPARE_OP(self, testnum, next_instr): w_2 = self.popvalue() w_1 = self.popvalue() - w_result = None - for i, attr in unrolling_compare_dispatch_table: - if i == testnum: - w_result = getattr(self, attr)(w_1, w_2) - break + if testnum == 0: + w_result = self.space.lt(w_1, w_2) + elif testnum == 1: + w_result = self.space.le(w_1, w_2) + elif testnum == 2: + w_result = self.space.eq(w_1, w_2) + elif testnum == 3: + w_result = self.space.ne(w_1, w_2) + elif testnum == 4: + w_result = self.space.gt(w_1, w_2) + elif testnum == 5: + w_result = self.space.ge(w_1, w_2) + elif testnum == 6: + w_result = self.space.contains(w_2, w_1) + elif testnum == 7: + w_result = self.space.not_(self.space.contains(w_2, w_1)) + elif testnum == 8: + w_result = self.space.is_(w_1, w_2) + elif testnum == 9: + w_result = self.space.not_(self.space.is_(w_1, w_2)) + elif testnum == 10: + w_result = self.cmp_exc_match(w_1, w_2) else: raise BytecodeCorruption("bad COMPARE_OP oparg") self.pushvalue(w_result) @@ -1086,49 +1248,6 @@ self.space.setitem(w_dict, w_key, w_value) -class __extend__(pyframe.CPythonFrame): - - def JUMP_IF_FALSE(self, stepby, next_instr): - w_cond = self.peekvalue() - if not self.space.is_true(w_cond): - next_instr += stepby - return next_instr - - def JUMP_IF_TRUE(self, stepby, next_instr): - w_cond = self.peekvalue() - if self.space.is_true(w_cond): - next_instr += stepby - return next_instr - - def BUILD_MAP(self, itemcount, next_instr): - if sys.version_info >= (2, 6): - # We could pre-allocate a dict here - # but for the moment this code is not translated. - pass - else: - if itemcount != 0: - raise BytecodeCorruption - w_dict = self.space.newdict() - self.pushvalue(w_dict) - - def STORE_MAP(self, zero, next_instr): - if sys.version_info >= (2, 6): - w_key = self.popvalue() - w_value = self.popvalue() - w_dict = self.peekvalue() - self.space.setitem(w_dict, w_key, w_value) - else: - raise BytecodeCorruption - - def LIST_APPEND(self, oparg, next_instr): - w = self.popvalue() - if sys.version_info < (2, 7): - v = self.popvalue() - else: - v = self.peekvalue(oparg - 1) - self.space.call_method(v, 'append', w) - - ### ____________________________________________________________ ### class ExitFrame(Exception): diff --git a/pypy/interpreter/test/test_argument.py b/pypy/interpreter/test/test_argument.py --- a/pypy/interpreter/test/test_argument.py +++ b/pypy/interpreter/test/test_argument.py @@ -128,7 +128,7 @@ def type(self, obj): class Type: - def getname(self, space, default='?'): + def getname(self, space): return type(obj).__name__ return Type() 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 @@ -953,10 +953,6 @@ assert i > -1 assert isinstance(co.co_consts[i], frozenset) - -class AppTestCallMethod(object): - spaceconfig = {'objspace.opcodes.CALL_METHOD': True} - def test_call_method_kwargs(self): source = """def _f(a): return a.f(a=a) diff --git a/pypy/interpreter/test/test_executioncontext.py b/pypy/interpreter/test/test_executioncontext.py --- a/pypy/interpreter/test/test_executioncontext.py +++ b/pypy/interpreter/test/test_executioncontext.py @@ -253,10 +253,6 @@ """) -class TestExecutionContextWithCallMethod(TestExecutionContext): - spaceconfig ={'objspace.opcodes.CALL_METHOD': True} - - class AppTestDelNotBlocked: def setup_method(self, meth): 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 @@ -812,10 +812,6 @@ assert len(called) == 1 assert isinstance(called[0], argument.Arguments) -class TestPassThroughArguments_CALL_METHOD(TestPassThroughArguments): - spaceconfig = dict(usemodules=('itertools',), **{ - "objspace.opcodes.CALL_METHOD": True - }) class AppTestKeywordsToBuiltinSanity(object): diff --git a/pypy/module/__pypy__/test/test_signal.py b/pypy/module/__pypy__/test/test_signal.py --- a/pypy/module/__pypy__/test/test_signal.py +++ b/pypy/module/__pypy__/test/test_signal.py @@ -28,16 +28,17 @@ import __pypy__, thread, signal, time, sys def subthread(): + print('subthread started') try: with __pypy__.thread.signals_enabled: thread.interrupt_main() for i in range(10): - print 'x' - time.sleep(0.1) + print('x') + time.sleep(0.25) except BaseException, e: interrupted.append(e) finally: - print 'subthread stops, interrupted=%r' % (interrupted,) + print('subthread stops, interrupted=%r' % (interrupted,)) done.append(None) # This is normally called by app_main.py @@ -53,13 +54,13 @@ try: done = [] interrupted = [] - print '--- start ---' + print('--- start ---') thread.start_new_thread(subthread, ()) for j in range(10): if len(done): break - print '.' - time.sleep(0.1) - print 'main thread loop done' + print('.') + time.sleep(0.25) + print('main thread loop done') assert len(done) == 1 assert len(interrupted) == 1 assert 'KeyboardInterrupt' in interrupted[0].__class__.__name__ @@ -80,7 +81,7 @@ def threadfunction(): pid = fork() if pid == 0: - print 'in child' + print('in child') # signal() only works from the 'main' thread signal.signal(signal.SIGUSR1, signal.SIG_IGN) os._exit(42) @@ -116,7 +117,7 @@ def subthread(): try: - time.sleep(0.25) + time.sleep(0.5) with __pypy__.thread.signals_enabled: thread.interrupt_main() except BaseException, e: diff --git a/pypy/module/_cffi_backend/ccallback.py b/pypy/module/_cffi_backend/ccallback.py --- a/pypy/module/_cffi_backend/ccallback.py +++ b/pypy/module/_cffi_backend/ccallback.py @@ -54,6 +54,13 @@ if rffi.cast(lltype.Signed, res) != clibffi.FFI_OK: raise OperationError(space.w_SystemError, space.wrap("libffi failed to build this callback")) + # + # We must setup the GIL here, in case the callback is invoked in + # some other non-Pythonic thread. This is the same as cffi on + # CPython. + if space.config.translation.thread: + from pypy.module.thread.os_thread import setup_threads + setup_threads(space) def get_closure(self): return rffi.cast(clibffi.FFI_CLOSUREP, self._cdata) 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 @@ -1516,13 +1516,18 @@ d = BStruct.fields assert d[0][1].offset == d[1][1].offset == d[2][1].offset == 0 assert d[3][1].offset == sizeof(BLong) - assert d[0][1].bitshift == 0 + def f(m, r): + if sys.byteorder == 'little': + return r + else: + return LONGBITS - m - r + assert d[0][1].bitshift == f(1, 0) assert d[0][1].bitsize == 1 - assert d[1][1].bitshift == 1 + assert d[1][1].bitshift == f(2, 1) assert d[1][1].bitsize == 2 - assert d[2][1].bitshift == 3 + assert d[2][1].bitshift == f(3, 3) assert d[2][1].bitsize == 3 - assert d[3][1].bitshift == 0 + assert d[3][1].bitshift == f(LONGBITS - 5, 0) assert d[3][1].bitsize == LONGBITS - 5 assert sizeof(BStruct) == 2 * sizeof(BLong) assert alignof(BStruct) == alignof(BLong) @@ -2856,7 +2861,7 @@ ('b1', BInt, 9), ('b2', BUInt, 7), ('c', BChar, -1)], -1, -1, -1, flag) - if flag % 2 == 0: # gcc and gcc ARM + if flag % 2 == 0: # gcc, any variant assert typeoffsetof(BStruct, 'c') == (BChar, 3) assert sizeof(BStruct) == 4 else: # msvc @@ -2864,6 +2869,31 @@ assert sizeof(BStruct) == 12 assert alignof(BStruct) == 4 # + p = newp(new_pointer_type(BStruct), None) + p.a = b'A' + p.b1 = -201 + p.b2 = 99 + p.c = b'\x9D' + raw = buffer(p)[:] + if sys.byteorder == 'little': + if flag == 0 or flag == 2: # gcc, little endian + assert raw == b'A7\xC7\x9D' + elif flag == 1: # msvc + assert raw == b'A\x00\x00\x007\xC7\x00\x00\x9D\x00\x00\x00' + elif flag == 4: # gcc, big endian + assert raw == b'A\xE3\x9B\x9D' + else: + raise AssertionError("bad flag") + else: + if flag == 0 or flag == 2: # gcc + assert raw == b'A\xC77\x9D' + elif flag == 1: # msvc + assert raw == b'A\x00\x00\x00\x00\x00\xC77\x9D\x00\x00\x00' + elif flag == 4: # gcc, big endian + assert raw == b'A\x9B\xE3\x9D' + else: + raise AssertionError("bad flag") + # BStruct = new_struct_type("struct foo2") complete_struct_or_union(BStruct, [('a', BChar, -1), ('', BShort, 9), @@ -2875,16 +2905,21 @@ elif flag == 1: # msvc assert sizeof(BStruct) == 6 assert alignof(BStruct) == 2 - else: # gcc ARM + elif flag == 2: # gcc ARM assert sizeof(BStruct) == 6 assert alignof(BStruct) == 2 + elif flag == 4: # gcc, big endian + assert sizeof(BStruct) == 5 + assert alignof(BStruct) == 1 + else: + raise AssertionError("bad flag") # BStruct = new_struct_type("struct foo2") complete_struct_or_union(BStruct, [('a', BChar, -1), ('', BInt, 0), ('', BInt, 0), ('c', BChar, -1)], -1, -1, -1, flag) - if flag == 0: # gcc + if flag == 0: # gcc assert typeoffsetof(BStruct, 'c') == (BChar, 4) assert sizeof(BStruct) == 5 assert alignof(BStruct) == 1 @@ -2892,10 +2927,16 @@ assert typeoffsetof(BStruct, 'c') == (BChar, 1) assert sizeof(BStruct) == 2 assert alignof(BStruct) == 1 - else: # gcc ARM + elif flag == 2: # gcc ARM assert typeoffsetof(BStruct, 'c') == (BChar, 4) assert sizeof(BStruct) == 8 assert alignof(BStruct) == 4 + elif flag == 4: # gcc, big endian + assert typeoffsetof(BStruct, 'c') == (BChar, 4) + assert sizeof(BStruct) == 5 + assert alignof(BStruct) == 1 + else: + raise AssertionError("bad flag") def test_bitfield_as_gcc(): @@ -2907,6 +2948,11 @@ def test_bitfield_as_arm_gcc(): _test_bitfield_details(flag=2) +def test_bitfield_as_big_endian(): + if '__pypy__' in sys.builtin_module_names: + py.test.skip("no big endian machine supported on pypy for now") + _test_bitfield_details(flag=4) + def test_version(): # this test is here mostly for PyPy diff --git a/pypy/module/_continuation/interp_pickle.py b/pypy/module/_continuation/interp_pickle.py --- a/pypy/module/_continuation/interp_pickle.py +++ b/pypy/module/_continuation/interp_pickle.py @@ -120,8 +120,7 @@ nkwds = (oparg >> 8) & 0xff if nkwds == 0: # only positional arguments # fast paths leaves things on the stack, pop them - if (frame.space.config.objspace.opcodes.CALL_METHOD and - opcode == map['CALL_METHOD']): + if opcode == map['CALL_METHOD']: frame.dropvalues(nargs + 2) elif opcode == map['CALL_FUNCTION']: frame.dropvalues(nargs + 1) diff --git a/pypy/module/_continuation/test/test_zpickle.py b/pypy/module/_continuation/test/test_zpickle.py --- a/pypy/module/_continuation/test/test_zpickle.py +++ b/pypy/module/_continuation/test/test_zpickle.py @@ -1,8 +1,7 @@ class AppTestCopy: spaceconfig = dict(usemodules=['_continuation'], - continuation=True, - CALL_METHOD=True) + continuation=True) def test_basic_setup(self): from _continuation import continulet @@ -104,7 +103,6 @@ spaceconfig = { "usemodules": ['_continuation', 'struct', 'binascii'], "continuation": True, - "CALL_METHOD": True, } def setup_class(cls): 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 @@ -437,14 +437,14 @@ return self.getrepr(self.space, info) def getdisplayname(self): + space = self.space w_name = self.w_name if w_name is None: return '?' - elif self.space.is_true(self.space.isinstance(w_name, - self.space.w_str)): - return "'%s'" % self.space.str_w(w_name) + elif space.isinstance_w(w_name, space.w_str): + return "'%s'" % space.str_w(w_name) else: - return self.space.str_w(self.space.repr(w_name)) + return space.str_w(space.repr(w_name)) def file_writelines(self, w_lines): """writelines(sequence_of_strings) -> None. Write the strings to the file. diff --git a/pypy/module/_file/test/test_file.py b/pypy/module/_file/test/test_file.py --- a/pypy/module/_file/test/test_file.py +++ b/pypy/module/_file/test/test_file.py @@ -385,6 +385,24 @@ raise Exception("time out") print 'Passed.' + def test_seek_from_cur_backwards_off_end(self): + import os + + f = self.file(self.temppath, "w+b") + f.write('123456789x12345678><123456789\n') + + f.seek(0, os.SEEK_END) + f.seek(-25, os.SEEK_CUR) + f.read(25) + f.seek(-25, os.SEEK_CUR) + try: + f.seek(-25, os.SEEK_CUR) + except IOError: + pass + else: + raise AssertionError("Didn't raise IOError") + assert f.tell() == 5 + class AppTestFile25: spaceconfig = dict(usemodules=("_file",)) diff --git a/pypy/module/_lsprof/test/test_cprofile.py b/pypy/module/_lsprof/test/test_cprofile.py --- a/pypy/module/_lsprof/test/test_cprofile.py +++ b/pypy/module/_lsprof/test/test_cprofile.py @@ -191,11 +191,6 @@ sys.path.pop(0) -class AppTestWithDifferentBytecodes(AppTestCProfile): - spaceconfig = AppTestCProfile.spaceconfig.copy() - spaceconfig['objspace.opcodes.CALL_METHOD'] = True - - expected_output = {} expected_output['print_stats'] = """\ 126 function calls (106 primitive calls) in 1.000 seconds 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 @@ -26,6 +26,9 @@ def try_ldflags(): yield ExternalCompilationInfo(libraries=['curses']) yield ExternalCompilationInfo(libraries=['curses', 'tinfo']) + yield ExternalCompilationInfo(libraries=['ncurses']) + yield ExternalCompilationInfo(libraries=['ncurses'], + library_dirs=['/usr/lib64']) def try_tools(): try: 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 @@ -175,8 +175,8 @@ state = '; dead' else: typename = space.type(w_obj).getname(space) - objname = w_obj.getname(space, '') - if objname: + objname = w_obj.getname(space) + if objname and objname != '?': state = "; to '%s' (%s)" % (typename, objname) else: state = "; to '%s'" % (typename,) 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 @@ -11,7 +11,7 @@ from rpython.rlib.unroll import unrolling_iterable from rpython.rlib.objectmodel import keepalive_until_here from rpython.rtyper.lltypesystem import lltype, rffi - +from pypy.objspace.std.floatobject import W_FloatObject @unwrap_spec(typecode=str) def w_array(space, w_cls, typecode, __args__): @@ -532,7 +532,7 @@ class TypeCode(object): - def __init__(self, itemtype, unwrap, canoverflow=False, signed=False): + def __init__(self, itemtype, unwrap, canoverflow=False, signed=False, method='__int__'): self.itemtype = itemtype self.bytes = rffi.sizeof(itemtype) self.arraytype = lltype.Array(itemtype, hints={'nolength': True}) @@ -540,6 +540,7 @@ self.signed = signed self.canoverflow = canoverflow self.w_class = None + self.method = method if self.canoverflow: assert self.bytes <= rffi.sizeof(rffi.ULONG) @@ -554,8 +555,8 @@ return True types = { - 'c': TypeCode(lltype.Char, 'str_w'), - 'u': TypeCode(lltype.UniChar, 'unicode_w'), + 'c': TypeCode(lltype.Char, 'str_w', method=''), + 'u': TypeCode(lltype.UniChar, 'unicode_w', method=''), 'b': TypeCode(rffi.SIGNEDCHAR, 'int_w', True, True), 'B': TypeCode(rffi.UCHAR, 'int_w', True), 'h': TypeCode(rffi.SHORT, 'int_w', True, True), @@ -567,8 +568,8 @@ # rbigint.touint() which # corresponds to the # C-type unsigned long - 'f': TypeCode(lltype.SingleFloat, 'float_w'), - 'd': TypeCode(lltype.Float, 'float_w'), + 'f': TypeCode(lltype.SingleFloat, 'float_w', method='__float__'), + 'd': TypeCode(lltype.Float, 'float_w', method='__float__'), } for k, v in types.items(): v.typecode = k @@ -613,7 +614,19 @@ def item_w(self, w_item): space = self.space unwrap = getattr(space, mytype.unwrap) - item = unwrap(w_item) + try: + item = unwrap(w_item) + except OperationError, e: + if isinstance(w_item, W_FloatObject): # Odd special case from cpython + raise + if mytype.method != '' and e.match(space, space.w_TypeError): + try: + item = unwrap(space.call_method(w_item, mytype.method)) + except OperationError: + msg = 'array item must be ' + mytype.unwrap[:-2] + raise OperationError(space.w_TypeError, space.wrap(msg)) + else: + raise if mytype.unwrap == 'bigint_w': try: item = item.touint() diff --git a/pypy/module/array/test/test_array.py b/pypy/module/array/test/test_array.py --- a/pypy/module/array/test/test_array.py +++ b/pypy/module/array/test/test_array.py @@ -874,6 +874,77 @@ assert l assert l[0] is None or len(l[0]) == 0 + def test_assign_object_with_special_methods(self): + from array import array + + class Num(object): + def __float__(self): + return 5.25 + + def __int__(self): + return 7 + + class NotNum(object): + pass + From noreply at buildbot.pypy.org Wed Sep 11 14:13:16 2013 From: noreply at buildbot.pypy.org (arigo) Date: Wed, 11 Sep 2013 14:13:16 +0200 (CEST) Subject: [pypy-commit] pypy default: Force waiting until most threads have finished. It was the cause of Message-ID: <20130911121316.58BC01C0175@cobra.cs.uni-duesseldorf.de> Author: Armin Rigo Branch: Changeset: r66902:5468ee20e516 Date: 2013-09-11 14:12 +0200 http://bitbucket.org/pypy/pypy/changeset/5468ee20e516/ Log: Force waiting until most threads have finished. It was the cause of intermittent failures in test_interrupt_main(), which could not create any new thread. diff --git a/pypy/module/thread/test/test_thread.py b/pypy/module/thread/test/test_thread.py --- a/pypy/module/thread/test/test_thread.py +++ b/pypy/module/thread/test/test_thread.py @@ -187,9 +187,12 @@ skip("this OS supports too many threads to check (> 1000)") lock = thread.allocate_lock() lock.acquire() + count = [0] def f(): + count[0] += 1 lock.acquire() lock.release() + count[0] -= 1 try: try: for i in range(1000): @@ -197,11 +200,15 @@ finally: lock.release() # wait a bit to allow most threads to finish now - self.busywait(2.0) + while count[0] > 10: + print count[0] # <- releases the GIL + print "ok." except (thread.error, MemoryError): pass else: raise Exception("could unexpectedly start 1000 threads") + # safety: check that we can start a new thread here + thread.start_new_thread(lambda: None, ()) def test_stack_size(self): import thread From noreply at buildbot.pypy.org Wed Sep 11 14:36:16 2013 From: noreply at buildbot.pypy.org (arigo) Date: Wed, 11 Sep 2013 14:36:16 +0200 (CEST) Subject: [pypy-commit] cffi default: issue 102: allow ffi.typeof() to work on functions taking a struct Message-ID: <20130911123616.040241C02DE@cobra.cs.uni-duesseldorf.de> Author: Armin Rigo Branch: Changeset: r1347:199010759f60 Date: 2013-09-11 14:35 +0200 http://bitbucket.org/cffi/cffi/changeset/199010759f60/ Log: issue 102: allow ffi.typeof() to work on functions taking a struct argument (with vengine_gen). Note that it still fails on functions taking an auto-completed struct. Unsure if and how to fix. diff --git a/cffi/api.py b/cffi/api.py --- a/cffi/api.py +++ b/cffi/api.py @@ -144,6 +144,9 @@ res = _builtin_function_type(cdecl) if res is not None: return res + if (isinstance(cdecl, types.FunctionType) + and hasattr(cdecl, '_cffi_base_type')): + return self._get_cached_btype(cdecl._cffi_base_type) raise TypeError(type(cdecl)) def sizeof(self, cdecl): diff --git a/cffi/vengine_gen.py b/cffi/vengine_gen.py --- a/cffi/vengine_gen.py +++ b/cffi/vengine_gen.py @@ -173,6 +173,7 @@ newfunction = self._load_constant(False, tp, name, module) else: indirections = [] + base_tp = tp if any(isinstance(typ, model.StructOrUnion) for typ in tp.args): indirect_args = [] for i, typ in enumerate(tp.args): @@ -186,16 +187,18 @@ wrappername = '_cffi_f_%s' % name newfunction = module.load_function(BFunc, wrappername) for i, typ in indirections: - newfunction = self._make_struct_wrapper(newfunction, i, typ) + newfunction = self._make_struct_wrapper(newfunction, i, typ, + base_tp) setattr(library, name, newfunction) type(library)._cffi_dir.append(name) - def _make_struct_wrapper(self, oldfunc, i, tp): + def _make_struct_wrapper(self, oldfunc, i, tp, base_tp): backend = self.ffi._backend BType = self.ffi._get_cached_btype(tp) def newfunc(*args): args = args[:i] + (backend.newp(BType, args[i]),) + args[i+1:] return oldfunc(*args) + newfunc._cffi_base_type = base_tp return newfunc # ---------- diff --git a/testing/test_verify.py b/testing/test_verify.py --- a/testing/test_verify.py +++ b/testing/test_verify.py @@ -1634,3 +1634,13 @@ #define FOO 42""") assert dir(lib) == ['AA', 'BB', 'FOO', 'somearray', 'somefunc', 'somevar', 'sv2'] + +def test_typeof_func_with_struct_argument(): + ffi = FFI() + ffi.cdef("""struct s { int a; }; int foo(struct s);""") + lib = ffi.verify("""struct s { int a; }; + int foo(struct s x) { return x.a; }""") + s = ffi.new("struct s *", [-1234]) + m = lib.foo(s[0]) + assert m == -1234 + assert repr(ffi.typeof(lib.foo)) == "" From noreply at buildbot.pypy.org Wed Sep 11 15:43:24 2013 From: noreply at buildbot.pypy.org (arigo) Date: Wed, 11 Sep 2013 15:43:24 +0200 (CEST) Subject: [pypy-commit] pypy default: Yay. Kill the special case 'indirect_call(instantiate, None)': Message-ID: <20130911134324.290C81C0929@cobra.cs.uni-duesseldorf.de> Author: Armin Rigo Branch: Changeset: r66903:d2f2a8c24277 Date: 2013-09-11 15:41 +0200 http://bitbucket.org/pypy/pypy/changeset/d2f2a8c24277/ Log: Yay. Kill the special case 'indirect_call(instantiate, None)': found out that we always have the correct list of graphs to put there. diff --git a/rpython/jit/codewriter/call.py b/rpython/jit/codewriter/call.py --- a/rpython/jit/codewriter/call.py +++ b/rpython/jit/codewriter/call.py @@ -92,17 +92,6 @@ else: assert op.opname == 'indirect_call' graphs = op.args[-1].value - if graphs is None: - # special case: handle the indirect call that goes to - # the 'instantiate' methods. This check is a bit imprecise - # but it's not too bad if we mistake a random indirect call - # for the one to 'instantiate'. - from rpython.rtyper.lltypesystem import rclass - CALLTYPE = op.args[0].concretetype - if (op.opname == 'indirect_call' and len(op.args) == 2 and - CALLTYPE == rclass.OBJECT_VTABLE.instantiate): - graphs = list(self._graphs_of_all_instantiate()) - # if graphs is not None: result = [] for graph in graphs: @@ -114,11 +103,6 @@ # residual call case: we don't need to look into any graph return None - def _graphs_of_all_instantiate(self): - for vtable in self.rtyper.lltype2vtable.values(): - if vtable.instantiate: - yield vtable.instantiate._obj.graph - def guess_call_kind(self, op, is_candidate=None): if op.opname == 'direct_call': funcptr = op.args[0].value diff --git a/rpython/jit/metainterp/test/test_ajit.py b/rpython/jit/metainterp/test/test_ajit.py --- a/rpython/jit/metainterp/test/test_ajit.py +++ b/rpython/jit/metainterp/test/test_ajit.py @@ -1411,7 +1411,6 @@ self.check_resops(call=2) def test_merge_guardclass_guardvalue(self): - from rpython.rlib.objectmodel import instantiate myjitdriver = JitDriver(greens = [], reds = ['x', 'l']) class A(object): @@ -1438,7 +1437,6 @@ self.check_resops(guard_class=0, guard_value=6) def test_merge_guardnonnull_guardclass(self): - from rpython.rlib.objectmodel import instantiate myjitdriver = JitDriver(greens = [], reds = ['x', 'l']) class A(object): @@ -1468,7 +1466,6 @@ def test_merge_guardnonnull_guardvalue(self): - from rpython.rlib.objectmodel import instantiate myjitdriver = JitDriver(greens = [], reds = ['x', 'l']) class A(object): @@ -1497,7 +1494,6 @@ def test_merge_guardnonnull_guardvalue_2(self): - from rpython.rlib.objectmodel import instantiate myjitdriver = JitDriver(greens = [], reds = ['x', 'l']) class A(object): @@ -1526,7 +1522,6 @@ def test_merge_guardnonnull_guardclass_guardvalue(self): - from rpython.rlib.objectmodel import instantiate myjitdriver = JitDriver(greens = [], reds = ['x', 'l']) class A(object): diff --git a/rpython/rtyper/lltypesystem/rpbc.py b/rpython/rtyper/lltypesystem/rpbc.py --- a/rpython/rtyper/lltypesystem/rpbc.py +++ b/rpython/rtyper/lltypesystem/rpbc.py @@ -377,11 +377,20 @@ # no __init__ here, AbstractClassesPBCRepr.__init__ is good enough def _instantiate_runtime_class(self, hop, vtypeptr, r_instance): - v_instantiate = hop.genop('getfield', [vtypeptr, hop.inputconst(Void, "instantiate")], resulttype=vtypeptr.concretetype.TO.instantiate) - possible_graphs = hop.inputconst(Void, - [desc.getclassdef(None).my_instantiate_graph for desc in self.s_pbc.descriptions] - ) - v_inst = hop.genop('indirect_call', [v_instantiate, possible_graphs], resulttype=vtypeptr.concretetype.TO.instantiate.TO.RESULT) + graphs = [] + for desc in self.s_pbc.descriptions: + classdef = desc.getclassdef(None) + assert hasattr(classdef, 'my_instantiate_graph') + graphs.append(classdef.my_instantiate_graph) + c_graphs = hop.inputconst(Void, graphs) + # + # "my_instantiate = typeptr.instantiate" + c_name = hop.inputconst(Void, 'instantiate') + v_instantiate = hop.genop('getfield', [vtypeptr, c_name], + resulttype = rclass.OBJECT_VTABLE.instantiate) + # "my_instantiate()" + v_inst = hop.genop('indirect_call', [v_instantiate, c_graphs], + resulttype = rclass.OBJECTPTR) return hop.genop('cast_pointer', [v_inst], resulttype=r_instance) def getlowleveltype(self): diff --git a/rpython/rtyper/rbuiltin.py b/rpython/rtyper/rbuiltin.py --- a/rpython/rtyper/rbuiltin.py +++ b/rpython/rtyper/rbuiltin.py @@ -705,10 +705,6 @@ assert isinstance(hop.args_r[0], rclass.InstanceRepr) return hop.args_r[0].rtype_isinstance(hop) -def ll_instantiate(typeptr): # NB. used by rpbc.ClassesPBCRepr as well - my_instantiate = typeptr.instantiate - return my_instantiate() - def rtype_instantiate(hop): hop.exception_cannot_occur() s_class = hop.args_s[0] @@ -716,10 +712,9 @@ if len(s_class.descriptions) != 1: # instantiate() on a variable class vtypeptr, = hop.inputargs(rclass.get_type_repr(hop.rtyper)) - v_inst = hop.gendirectcall(ll_instantiate, vtypeptr) - return hop.genop('cast_pointer', [v_inst], # v_type implicit in r_result - resulttype = hop.r_result.lowleveltype) - + r_class = hop.args_r[0] + return r_class._instantiate_runtime_class(hop, vtypeptr, + hop.r_result.lowleveltype) classdef = s_class.any_description().getuniqueclassdef() return rclass.rtype_new_instance(hop.rtyper, classdef, hop.llops) diff --git a/rpython/translator/backendopt/gilanalysis.py b/rpython/translator/backendopt/gilanalysis.py --- a/rpython/translator/backendopt/gilanalysis.py +++ b/rpython/translator/backendopt/gilanalysis.py @@ -26,9 +26,6 @@ return False else: return False - - def analyze_instantiate_call(self, seen=None): - return False def analyze_simple_operation(self, op, graphinfo): return False diff --git a/rpython/translator/backendopt/graphanalyze.py b/rpython/translator/backendopt/graphanalyze.py --- a/rpython/translator/backendopt/graphanalyze.py +++ b/rpython/translator/backendopt/graphanalyze.py @@ -68,9 +68,6 @@ result, self.analyze_direct_call(graph, seen)) return result - def analyze_instantiate_call(self, seen=None): - return self.top_result() - def analyze_link(self, graph, link): return self.bottom_result() @@ -79,7 +76,7 @@ def compute_graph_info(self, graph): return None - def analyze(self, op, seen=None, graphinfo=None, block=None): + def analyze(self, op, seen=None, graphinfo=None): if op.opname == "direct_call": graph = get_graph(op.args[0], self.translator) if graph is None: @@ -94,18 +91,6 @@ elif op.opname == "indirect_call": graphs = op.args[-1].value if graphs is None: - if block is not None: - v_func = op.args[0] - for op1 in block.operations: - if (v_func is op1.result and - op1.opname == 'getfield' and - op1.args[0].concretetype == rclass.CLASSTYPE and - op1.args[1].value == 'instantiate'): - x = self.analyze_instantiate_call(seen) - if self.verbose and x: - self.dump_info('analyze_instantiate(%s): %r' % ( - graphs, x)) - return x if self.verbose: self.dump_info('%s to unknown' % (op,)) return self.top_result() @@ -143,7 +128,7 @@ for op in block.operations: result = self.add_to_result( result, - self.analyze(op, seen, graphinfo, block=block) + self.analyze(op, seen, graphinfo) ) if self.is_top_result(result): break @@ -177,7 +162,7 @@ graphs = self.translator.graphs for graph in graphs: for block, op in graph.iterblockops(): - self.analyze(op, block=block) + self.analyze(op) class Dependency(object): diff --git a/rpython/translator/backendopt/test/test_writeanalyze.py b/rpython/translator/backendopt/test/test_writeanalyze.py --- a/rpython/translator/backendopt/test/test_writeanalyze.py +++ b/rpython/translator/backendopt/test/test_writeanalyze.py @@ -169,8 +169,6 @@ assert not wa.analyze(op_call_m) def test_instantiate(self): - # instantiate is interesting, because it leads to one of the few cases of - # an indirect call without a list of graphs from rpython.rlib.objectmodel import instantiate class A: pass @@ -187,7 +185,7 @@ t, wa = self.translate(f, [int]) fgraph = graphof(t, f) result = wa.analyze(fgraph.startblock.operations[0]) - assert result is top_set + assert not result def test_llexternal(self): from rpython.rtyper.lltypesystem.rffi import llexternal From noreply at buildbot.pypy.org Wed Sep 11 15:47:26 2013 From: noreply at buildbot.pypy.org (arigo) Date: Wed, 11 Sep 2013 15:47:26 +0200 (CEST) Subject: [pypy-commit] pypy stmgc-c4: hg merge default Message-ID: <20130911134726.1A9A41C0175@cobra.cs.uni-duesseldorf.de> Author: Armin Rigo Branch: stmgc-c4 Changeset: r66904:287326e8e482 Date: 2013-09-11 15:46 +0200 http://bitbucket.org/pypy/pypy/changeset/287326e8e482/ Log: hg merge default diff --git a/lib-python/2.7/argparse.py b/lib-python/2.7/argparse.py --- a/lib-python/2.7/argparse.py +++ b/lib-python/2.7/argparse.py @@ -1780,7 +1780,19 @@ # error if this argument is not allowed with other previously # seen arguments, assuming that actions that use the default # value don't really count as "present" - if argument_values is not action.default: + + # XXX PyPy bug-to-bug compatibility: "is" on primitive types + # is not consistent in CPython. We'll assume it is close + # enough for ints (which is true only for "small ints"), but + # for floats and longs and complexes we'll go for the option + # of forcing "is" to say False, like it usually does on + # CPython. A fix is pending on CPython trunk + # (http://bugs.python.org/issue18943) but that might change + # the details of the semantics and so not be applied to 2.7. + # See the line AA below. + + if (argument_values is not action.default or + type(argument_values) in (float, long, complex)): # AA seen_non_default_actions.add(action) for conflict_action in action_conflicts.get(action, []): if conflict_action in seen_non_default_actions: diff --git a/pypy/module/thread/test/test_thread.py b/pypy/module/thread/test/test_thread.py --- a/pypy/module/thread/test/test_thread.py +++ b/pypy/module/thread/test/test_thread.py @@ -187,9 +187,12 @@ skip("this OS supports too many threads to check (> 1000)") lock = thread.allocate_lock() lock.acquire() + count = [0] def f(): + count[0] += 1 lock.acquire() lock.release() + count[0] -= 1 try: try: for i in range(1000): @@ -197,11 +200,15 @@ finally: lock.release() # wait a bit to allow most threads to finish now - self.busywait(2.0) + while count[0] > 10: + print count[0] # <- releases the GIL + print "ok." except (thread.error, MemoryError): pass else: raise Exception("could unexpectedly start 1000 threads") + # safety: check that we can start a new thread here + thread.start_new_thread(lambda: None, ()) def test_stack_size(self): import thread diff --git a/rpython/jit/codewriter/call.py b/rpython/jit/codewriter/call.py --- a/rpython/jit/codewriter/call.py +++ b/rpython/jit/codewriter/call.py @@ -92,17 +92,6 @@ else: assert op.opname == 'indirect_call' graphs = op.args[-1].value - if graphs is None: - # special case: handle the indirect call that goes to - # the 'instantiate' methods. This check is a bit imprecise - # but it's not too bad if we mistake a random indirect call - # for the one to 'instantiate'. - from rpython.rtyper.lltypesystem import rclass - CALLTYPE = op.args[0].concretetype - if (op.opname == 'indirect_call' and len(op.args) == 2 and - CALLTYPE == rclass.OBJECT_VTABLE.instantiate): - graphs = list(self._graphs_of_all_instantiate()) - # if graphs is not None: result = [] for graph in graphs: @@ -114,11 +103,6 @@ # residual call case: we don't need to look into any graph return None - def _graphs_of_all_instantiate(self): - for vtable in self.rtyper.lltype2vtable.values(): - if vtable.instantiate: - yield vtable.instantiate._obj.graph - def guess_call_kind(self, op, is_candidate=None): if op.opname == 'direct_call': funcptr = op.args[0].value 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 @@ -166,9 +166,6 @@ 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/test/test_ajit.py b/rpython/jit/metainterp/test/test_ajit.py --- a/rpython/jit/metainterp/test/test_ajit.py +++ b/rpython/jit/metainterp/test/test_ajit.py @@ -1411,7 +1411,6 @@ self.check_resops(call=2) def test_merge_guardclass_guardvalue(self): - from rpython.rlib.objectmodel import instantiate myjitdriver = JitDriver(greens = [], reds = ['x', 'l']) class A(object): @@ -1438,7 +1437,6 @@ self.check_resops(guard_class=0, guard_value=6) def test_merge_guardnonnull_guardclass(self): - from rpython.rlib.objectmodel import instantiate myjitdriver = JitDriver(greens = [], reds = ['x', 'l']) class A(object): @@ -1468,7 +1466,6 @@ def test_merge_guardnonnull_guardvalue(self): - from rpython.rlib.objectmodel import instantiate myjitdriver = JitDriver(greens = [], reds = ['x', 'l']) class A(object): @@ -1497,7 +1494,6 @@ def test_merge_guardnonnull_guardvalue_2(self): - from rpython.rlib.objectmodel import instantiate myjitdriver = JitDriver(greens = [], reds = ['x', 'l']) class A(object): @@ -1526,7 +1522,6 @@ def test_merge_guardnonnull_guardclass_guardvalue(self): - from rpython.rlib.objectmodel import instantiate myjitdriver = JitDriver(greens = [], reds = ['x', 'l']) class A(object): diff --git a/rpython/rlib/rsre/rpy/__init__.py b/rpython/rlib/rsre/rpy/__init__.py new file mode 100644 --- /dev/null +++ b/rpython/rlib/rsre/rpy/__init__.py @@ -0,0 +1,1 @@ +from ._sre import get_code diff --git a/rpython/rlib/rsre/rpy.py b/rpython/rlib/rsre/rpy/_sre.py rename from rpython/rlib/rsre/rpy.py rename to rpython/rlib/rsre/rpy/_sre.py --- a/rpython/rlib/rsre/rpy.py +++ b/rpython/rlib/rsre/rpy/_sre.py @@ -1,46 +1,24 @@ from rpython.rlib.rsre import rsre_char -from rpython.rlib.rsre.rsre_core import match from rpython.rlib.rarithmetic import intmask -def get_hacked_sre_compile(my_compile): - """Return a copy of the sre_compile module for which the _sre - module is a custom module that has _sre.compile == my_compile - and CODESIZE == rsre_char.CODESIZE. - """ - import sre_compile, sre_constants, __builtin__, new - sre_hacked = new.module("_sre_hacked") - sre_hacked.compile = my_compile - sre_hacked.MAGIC = sre_compile.MAGIC - sre_hacked.CODESIZE = rsre_char.CODESIZE - sre_hacked.MAXREPEAT = sre_constants.MAX_REPEAT - sre_hacked.getlower = rsre_char.getlower - def my_import(name, *args): - if name == '_sre': - return sre_hacked - else: - return default_import(name, *args) - src = sre_compile.__file__ - if src.lower().endswith('.pyc') or src.lower().endswith('.pyo'): - src = src[:-1] - mod = new.module("sre_compile_hacked") - default_import = __import__ - try: - __builtin__.__import__ = my_import - execfile(src, mod.__dict__) - finally: - __builtin__.__import__ = default_import - return mod + +MAGIC = 20031017 +CODESIZE = rsre_char.CODESIZE +getlower = rsre_char.getlower + class GotIt(Exception): pass -def my_compile(pattern, flags, code, *args): + +def compile(pattern, flags, code, *args): raise GotIt([intmask(i) for i in code], flags, args) -sre_compile_hacked = get_hacked_sre_compile(my_compile) + def get_code(regexp, flags=0, allargs=False): + from . import sre_compile try: - sre_compile_hacked.compile(regexp, flags) + sre_compile.compile(regexp, flags) except GotIt, e: pass else: diff --git a/lib-python/2.7/sre_compile.py b/rpython/rlib/rsre/rpy/sre_compile.py copy from lib-python/2.7/sre_compile.py copy to rpython/rlib/rsre/rpy/sre_compile.py --- a/lib-python/2.7/sre_compile.py +++ b/rpython/rlib/rsre/rpy/sre_compile.py @@ -8,11 +8,11 @@ # See the sre.py file for information on usage and redistribution. # -"""Internal support module for sre""" +"""Internal support module for sre (copied from CPython 2.7.3)""" -import _sre, sys -import sre_parse -from sre_constants import * +import sys +from . import _sre, sre_parse +from .sre_constants import * assert _sre.MAGIC == MAGIC, "SRE module mismatch" diff --git a/lib-python/2.7/sre_constants.py b/rpython/rlib/rsre/rpy/sre_constants.py copy from lib-python/2.7/sre_constants.py copy to rpython/rlib/rsre/rpy/sre_constants.py --- a/lib-python/2.7/sre_constants.py +++ b/rpython/rlib/rsre/rpy/sre_constants.py @@ -9,7 +9,7 @@ # See the sre.py file for information on usage and redistribution. # -"""Internal support module for sre""" +"""Internal support module for sre (copied from CPython 2.7.3)""" # update when constants are added or removed @@ -20,10 +20,8 @@ MAXREPEAT = 65535 # SRE standard exception (access as sre.error) -# should this really be here? - -class error(Exception): - pass +# (use the real re.error exception class) +from re import error # operators diff --git a/lib-python/2.7/sre_parse.py b/rpython/rlib/rsre/rpy/sre_parse.py copy from lib-python/2.7/sre_parse.py copy to rpython/rlib/rsre/rpy/sre_parse.py --- a/lib-python/2.7/sre_parse.py +++ b/rpython/rlib/rsre/rpy/sre_parse.py @@ -8,19 +8,13 @@ # See the sre.py file for information on usage and redistribution. # -"""Internal support module for sre""" +"""Internal support module for sre (copied from CPython 2.7.3)""" # XXX: show string offset and offending character for all errors import sys -from sre_constants import * - -try: - from __pypy__ import newdict -except ImportError: - assert '__pypy__' not in sys.builtin_module_names - newdict = lambda _ : {} +from .sre_constants import * SPECIAL_CHARS = ".\\[{()*+?^$|" REPEAT_CHARS = "*+?{" @@ -74,7 +68,7 @@ self.flags = 0 self.open = [] self.groups = 1 - self.groupdict = newdict("module") + self.groupdict = {} def opengroup(self, name=None): gid = self.groups self.groups = gid + 1 diff --git a/rpython/rlib/rsre/rsre_re.py b/rpython/rlib/rsre/rsre_re.py --- a/rpython/rlib/rsre/rsre_re.py +++ b/rpython/rlib/rsre/rsre_re.py @@ -286,8 +286,8 @@ class Scanner: # This class is copied directly from re.py. def __init__(self, lexicon, flags=0): - from sre_constants import BRANCH, SUBPATTERN - import sre_parse + from rpython.rlib.rsre.rpy.sre_constants import BRANCH, SUBPATTERN + from rpython.rlib.rsre.rpy import sre_parse self.lexicon = lexicon # combine phrases into a compound pattern p = [] diff --git a/rpython/rlib/rsre/test/test_char.py b/rpython/rlib/rsre/test/test_char.py --- a/rpython/rlib/rsre/test/test_char.py +++ b/rpython/rlib/rsre/test/test_char.py @@ -48,7 +48,7 @@ assert not rsre_char.is_uni_word(ord(',')) def test_category(): - from sre_constants import CHCODES + from rpython.rlib.rsre.rpy.sre_constants import CHCODES cat = rsre_char.category_dispatch # assert cat(CHCODES["category_digit"], ord('1')) diff --git a/rpython/rtyper/lltypesystem/rpbc.py b/rpython/rtyper/lltypesystem/rpbc.py --- a/rpython/rtyper/lltypesystem/rpbc.py +++ b/rpython/rtyper/lltypesystem/rpbc.py @@ -377,11 +377,20 @@ # no __init__ here, AbstractClassesPBCRepr.__init__ is good enough def _instantiate_runtime_class(self, hop, vtypeptr, r_instance): - v_instantiate = hop.genop('getfield', [vtypeptr, hop.inputconst(Void, "instantiate")], resulttype=vtypeptr.concretetype.TO.instantiate) - possible_graphs = hop.inputconst(Void, - [desc.getclassdef(None).my_instantiate_graph for desc in self.s_pbc.descriptions] - ) - v_inst = hop.genop('indirect_call', [v_instantiate, possible_graphs], resulttype=vtypeptr.concretetype.TO.instantiate.TO.RESULT) + graphs = [] + for desc in self.s_pbc.descriptions: + classdef = desc.getclassdef(None) + assert hasattr(classdef, 'my_instantiate_graph') + graphs.append(classdef.my_instantiate_graph) + c_graphs = hop.inputconst(Void, graphs) + # + # "my_instantiate = typeptr.instantiate" + c_name = hop.inputconst(Void, 'instantiate') + v_instantiate = hop.genop('getfield', [vtypeptr, c_name], + resulttype = rclass.OBJECT_VTABLE.instantiate) + # "my_instantiate()" + v_inst = hop.genop('indirect_call', [v_instantiate, c_graphs], + resulttype = rclass.OBJECTPTR) return hop.genop('cast_pointer', [v_inst], resulttype=r_instance) def getlowleveltype(self): diff --git a/rpython/rtyper/rbuiltin.py b/rpython/rtyper/rbuiltin.py --- a/rpython/rtyper/rbuiltin.py +++ b/rpython/rtyper/rbuiltin.py @@ -715,10 +715,6 @@ assert isinstance(hop.args_r[0], rclass.InstanceRepr) return hop.args_r[0].rtype_isinstance(hop) -def ll_instantiate(typeptr): # NB. used by rpbc.ClassesPBCRepr as well - my_instantiate = typeptr.instantiate - return my_instantiate() - def rtype_instantiate(hop): hop.exception_cannot_occur() s_class = hop.args_s[0] @@ -726,10 +722,9 @@ if len(s_class.descriptions) != 1: # instantiate() on a variable class vtypeptr, = hop.inputargs(rclass.get_type_repr(hop.rtyper)) - v_inst = hop.gendirectcall(ll_instantiate, vtypeptr) - return hop.genop('cast_pointer', [v_inst], # v_type implicit in r_result - resulttype = hop.r_result.lowleveltype) - + r_class = hop.args_r[0] + return r_class._instantiate_runtime_class(hop, vtypeptr, + hop.r_result.lowleveltype) classdef = s_class.any_description().getuniqueclassdef() return rclass.rtype_new_instance(hop.rtyper, classdef, hop.llops) diff --git a/rpython/translator/backendopt/gilanalysis.py b/rpython/translator/backendopt/gilanalysis.py --- a/rpython/translator/backendopt/gilanalysis.py +++ b/rpython/translator/backendopt/gilanalysis.py @@ -26,9 +26,6 @@ return False else: return False - - def analyze_instantiate_call(self, seen=None): - return False def analyze_simple_operation(self, op, graphinfo): return False diff --git a/rpython/translator/backendopt/graphanalyze.py b/rpython/translator/backendopt/graphanalyze.py --- a/rpython/translator/backendopt/graphanalyze.py +++ b/rpython/translator/backendopt/graphanalyze.py @@ -68,9 +68,6 @@ result, self.analyze_direct_call(graph, seen)) return result - def analyze_instantiate_call(self, seen=None): - return self.top_result() - def analyze_link(self, graph, link): return self.bottom_result() @@ -79,7 +76,7 @@ def compute_graph_info(self, graph): return None - def analyze(self, op, seen=None, graphinfo=None, block=None): + def analyze(self, op, seen=None, graphinfo=None): if op.opname == "direct_call": try: graph = get_graph(op.args[0], self.translator) @@ -100,18 +97,6 @@ elif op.opname == "indirect_call": graphs = op.args[-1].value if graphs is None: - if block is not None: - v_func = op.args[0] - for op1 in block.operations: - if (v_func is op1.result and - op1.opname == 'getfield' and - op1.args[0].concretetype == rclass.CLASSTYPE and - op1.args[1].value == 'instantiate'): - x = self.analyze_instantiate_call(seen) - if self.verbose and x: - self.dump_info('analyze_instantiate(%s): %r' % ( - graphs, x)) - return x if self.verbose: self.dump_info('%s to unknown' % (op,)) return self.top_result() @@ -149,7 +134,7 @@ for op in block.operations: result = self.add_to_result( result, - self.analyze(op, seen, graphinfo, block=block) + self.analyze(op, seen, graphinfo) ) if self.is_top_result(result): break @@ -183,7 +168,7 @@ graphs = self.translator.graphs for graph in graphs: for block, op in graph.iterblockops(): - self.analyze(op, block=block) + self.analyze(op) class Dependency(object): diff --git a/rpython/translator/backendopt/test/test_writeanalyze.py b/rpython/translator/backendopt/test/test_writeanalyze.py --- a/rpython/translator/backendopt/test/test_writeanalyze.py +++ b/rpython/translator/backendopt/test/test_writeanalyze.py @@ -169,8 +169,6 @@ assert not wa.analyze(op_call_m) def test_instantiate(self): - # instantiate is interesting, because it leads to one of the few cases of - # an indirect call without a list of graphs from rpython.rlib.objectmodel import instantiate class A: pass @@ -187,7 +185,7 @@ t, wa = self.translate(f, [int]) fgraph = graphof(t, f) result = wa.analyze(fgraph.startblock.operations[0]) - assert result is top_set + assert not result def test_llexternal(self): from rpython.rtyper.lltypesystem.rffi import llexternal diff --git a/rpython/translator/stm/inevitable.py b/rpython/translator/stm/inevitable.py --- a/rpython/translator/stm/inevitable.py +++ b/rpython/translator/stm/inevitable.py @@ -96,14 +96,6 @@ if tographs is not None: # Set of RPython functions return False - # special-case to detect 'instantiate' - v_func = op.args[0] - for op1 in block.operations: - if (v_func is op1.result and - op1.opname == 'getfield' and - op1.args[0].concretetype == rclass.CLASSTYPE and - op1.args[1].value == 'instantiate'): - return False # unknown function return True From noreply at buildbot.pypy.org Wed Sep 11 19:17:39 2013 From: noreply at buildbot.pypy.org (arigo) Date: Wed, 11 Sep 2013 19:17:39 +0200 (CEST) Subject: [pypy-commit] pypy stmgc-c4: Don't force the frame for the JIT. Temporary workaround. Message-ID: <20130911171739.ABEF41C0165@cobra.cs.uni-duesseldorf.de> Author: Armin Rigo Branch: stmgc-c4 Changeset: r66905:0002ef65e97b Date: 2013-09-11 19:16 +0200 http://bitbucket.org/pypy/pypy/changeset/0002ef65e97b/ Log: Don't force the frame for the JIT. Temporary workaround. diff --git a/pypy/interpreter/executioncontext.py b/pypy/interpreter/executioncontext.py --- a/pypy/interpreter/executioncontext.py +++ b/pypy/interpreter/executioncontext.py @@ -60,6 +60,7 @@ def enter(self, frame): if self.space.config.translation.stm: + if not self.space.config.translation.jit: # XXX from pypy.module.thread.stm import enter_frame enter_frame(self, frame) frame.f_backref = self.topframeref @@ -87,6 +88,7 @@ self.space.frame_trace_action.fire() if self.space.config.translation.stm: + if not self.space.config.translation.jit: # XXX from pypy.module.thread.stm import leave_frame leave_frame(self, frame) From noreply at buildbot.pypy.org Wed Sep 11 20:05:59 2013 From: noreply at buildbot.pypy.org (Raemi) Date: Wed, 11 Sep 2013 20:05:59 +0200 (CEST) Subject: [pypy-commit] pypy stmgc-c4: try to reduce becomeinevitable because of indirect_calls in blackhole.py (call_stub) Message-ID: <20130911180559.261171C12EC@cobra.cs.uni-duesseldorf.de> Author: Remi Meier Branch: stmgc-c4 Changeset: r66906:32a78cfb3fbc Date: 2013-09-11 20:04 +0200 http://bitbucket.org/pypy/pypy/changeset/32a78cfb3fbc/ Log: try to reduce becomeinevitable because of indirect_calls in blackhole.py (call_stub) 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 @@ -404,12 +404,27 @@ category = 'i' else: assert 0 - source = py.code.Source(""" - def call_stub(func, args_i, args_r, args_f): - fnptr = rffi.cast(lltype.Ptr(FUNC), func) - res = support.maybe_on_top_of_llinterp(rtyper, fnptr)(%(args)s) - return %(result)s - """ % locals()) + + llop1 = llop + if not stm or ( + self.extrainfo and self.extrainfo.call_needs_inevitable()): + source = py.code.Source(""" + def call_stub(func, args_i, args_r, args_f): + fnptr = rffi.cast(lltype.Ptr(FUNC), func) + res = support.maybe_on_top_of_llinterp(rtyper, fnptr)(%(args)s) + return %(result)s + """ % locals()) + else: + # the above 'source' works on STM too, but always forces + # the transaction to become inevitable. Using jit_assembler_call + # in cases where it is not needed avoids that. + source = py.code.Source(""" + def call_stub(func, args_i, args_r, args_f): + fnptr = rffi.cast(lltype.Ptr(FUNC), func) + fun = support.maybe_on_top_of_llinterp(rtyper, fnptr) + res = llop1.jit_assembler_call(RESULT, fun, %(args)s) + return %(result)s + """ % locals()) ARGS = [TYPE(arg) for arg in self.arg_classes] FUNC = lltype.FuncType(ARGS, RESULT) d = globals().copy() diff --git a/rpython/jit/backend/llsupport/stmrewrite.py b/rpython/jit/backend/llsupport/stmrewrite.py --- a/rpython/jit/backend/llsupport/stmrewrite.py +++ b/rpython/jit/backend/llsupport/stmrewrite.py @@ -1,4 +1,5 @@ from rpython.jit.backend.llsupport.rewrite import GcRewriterAssembler +from rpython.jit.backend.llsupport.descr import CallDescr from rpython.jit.metainterp.resoperation import ResOperation, rop from rpython.jit.metainterp.history import BoxPtr, ConstPtr, ConstInt from rpython.rlib.objectmodel import specialize @@ -108,7 +109,13 @@ elif op.getopnum() == rop.CALL_ASSEMBLER: self.handle_call_assembler(op) else: - self.newops.append(op) + descr = op.getdescr() + assert not descr or isinstance(descr, CallDescr) + if descr and descr.get_extra_info() and \ + descr.get_extra_info().call_needs_inevitable(): + self.fallback_inevitable(op) + else: + self.newops.append(op) self.known_category.clear() continue # ---------- copystrcontent ---------- diff --git a/rpython/jit/backend/llsupport/test/test_descr.py b/rpython/jit/backend/llsupport/test/test_descr.py --- a/rpython/jit/backend/llsupport/test/test_descr.py +++ b/rpython/jit/backend/llsupport/test/test_descr.py @@ -353,6 +353,32 @@ descr5f = get_call_descr(c0, [lltype.Char], lltype.SingleFloat) assert repr_of_descr(descr5f) == '' + +def test_call_stubs_inevitable(): + for inev in (True, False): + class fakeextrainfo: + def call_needs_inevitable(self): + return inev + class fakertyper: + class annotator: + class translator: + class config: + class translation: + stm = True + + c0 = GcCache(False, rtyper=fakertyper()) + ARGS = [lltype.Char, lltype.Signed] + RES = lltype.Char + descr1 = get_call_descr(c0, ARGS, RES, extrainfo=fakeextrainfo()) + def f(a, b): + return 'c' + + fnptr = llhelper(lltype.Ptr(lltype.FuncType(ARGS, RES)), f) + + res = descr1.call_stub_i(rffi.cast(lltype.Signed, fnptr), + [1, 2], None, None) + assert res == ord('c') + def test_call_stubs_1(): c0 = GcCache(False) ARGS = [lltype.Char, lltype.Signed] diff --git a/rpython/jit/backend/llsupport/test/test_stmrewrite.py b/rpython/jit/backend/llsupport/test/test_stmrewrite.py --- a/rpython/jit/backend/llsupport/test/test_stmrewrite.py +++ b/rpython/jit/backend/llsupport/test/test_stmrewrite.py @@ -62,6 +62,29 @@ RewriteTests.check_rewrite(self, frm_operations, to_operations, **namespace) + def test_inevitable_calls(self): + c1 = GcCache(True) + T = lltype.GcStruct('T') + U = lltype.GcStruct('U', ('x', lltype.Signed)) + for inev in (True, False): + class fakeextrainfo: + def call_needs_inevitable(self): + return inev + + calldescr = get_call_descr(c1, [lltype.Ptr(T)], lltype.Ptr(U), + fakeextrainfo()) + + self.check_rewrite(""" + [] + call(123, descr=cd) + jump() + """,""" + [] + %s + call(123, descr=cd) + jump() + """ % ("$INEV" if inev else "",), cd=calldescr) + def test_rewrite_one_setfield_gc(self): self.check_rewrite(""" [p1, p2] diff --git a/rpython/jit/codewriter/call.py b/rpython/jit/codewriter/call.py --- a/rpython/jit/codewriter/call.py +++ b/rpython/jit/codewriter/call.py @@ -196,6 +196,12 @@ elidable = False loopinvariant = False call_release_gil_target = llmemory.NULL + needs_inevitable = False + if op.opname == 'indirect_call' or op.opname == 'direct_call': + from rpython.translator.stm.inevitable import ( + should_turn_inevitable_call) + needs_inevitable = bool(should_turn_inevitable_call(op)) + if op.opname == "direct_call": funcobj = op.args[0].value._obj assert getattr(funcobj, 'calling_conv', 'c') == 'c', ( @@ -206,7 +212,8 @@ if loopinvariant: assert not NON_VOID_ARGS, ("arguments not supported for " "loop-invariant function!") - if getattr(func, "_call_aroundstate_target_", None): + funcptr = getattr(func, "_call_aroundstate_target_", None) + if funcptr: call_release_gil_target = func._call_aroundstate_target_ call_release_gil_target = llmemory.cast_ptr_to_adr( call_release_gil_target) @@ -234,6 +241,7 @@ effectinfo = effectinfo_from_writeanalyze( self.readwrite_analyzer.analyze(op), self.cpu, extraeffect, oopspecindex, can_invalidate, call_release_gil_target, + needs_inevitable ) # assert effectinfo is not None 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 @@ -96,14 +96,16 @@ extraeffect=EF_CAN_RAISE, oopspecindex=OS_NONE, can_invalidate=False, - call_release_gil_target=llmemory.NULL): + call_release_gil_target=llmemory.NULL, + needs_inevitable=False): key = (frozenset_or_none(readonly_descrs_fields), frozenset_or_none(readonly_descrs_arrays), frozenset_or_none(write_descrs_fields), frozenset_or_none(write_descrs_arrays), extraeffect, oopspecindex, - can_invalidate) + can_invalidate, + needs_inevitable) if call_release_gil_target: key += (object(),) # don't care about caching in this case if key in cls._cache: @@ -131,6 +133,7 @@ result.write_descrs_arrays = write_descrs_arrays result.extraeffect = extraeffect result.can_invalidate = can_invalidate + result.needs_inevitable = needs_inevitable result.oopspecindex = oopspecindex result.call_release_gil_target = call_release_gil_target if result.check_can_raise(): @@ -157,6 +160,9 @@ def is_call_release_gil(self): return bool(self.call_release_gil_target) + def call_needs_inevitable(self): + return self.needs_inevitable + def frozenset_or_none(x): if x is None: @@ -172,7 +178,8 @@ extraeffect=EffectInfo.EF_CAN_RAISE, oopspecindex=EffectInfo.OS_NONE, can_invalidate=False, - call_release_gil_target=llmemory.NULL): + call_release_gil_target=llmemory.NULL, + needs_inevitable=False): from rpython.translator.backendopt.writeanalyze import top_set if effects is top_set or extraeffect == EffectInfo.EF_RANDOM_EFFECTS: readonly_descrs_fields = None @@ -221,7 +228,8 @@ extraeffect, oopspecindex, can_invalidate, - call_release_gil_target) + call_release_gil_target, + needs_inevitable) def consider_struct(TYPE, fieldname): if fieldType(TYPE, fieldname) is lltype.Void: 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 @@ -198,6 +198,33 @@ call_descr = cc.getcalldescr(op) assert call_descr.extrainfo.has_random_effects() assert call_descr.extrainfo.is_call_release_gil() is False + assert call_descr.extrainfo.call_needs_inevitable() is False + +def test_releases_gil_analyzer_needs_inevitable(): + from rpython.jit.backend.llgraph.runner import LLGraphCPU + + for transactionsafe in (True, False): + T = rffi.CArrayPtr(rffi.TIME_T) + external = rffi.llexternal("time", [T], rffi.TIME_T, + _nowrapper=True, + threadsafe=False, + transactionsafe=transactionsafe) + + @jit.dont_look_inside + def f(): + return external(lltype.nullptr(T.TO)) + + rtyper = support.annotate(f, []) + jitdriver_sd = FakeJitDriverSD(rtyper.annotator.translator.graphs[0]) + cc = CallControl(LLGraphCPU(rtyper), jitdrivers_sd=[jitdriver_sd]) + res = cc.find_all_graphs(FakePolicy()) + [f_graph] = [x for x in res if x.func is f] + [block, _] = list(f_graph.iterblocks()) + [op] = block.operations + call_descr = cc.getcalldescr(op) + assert call_descr.extrainfo.is_call_release_gil() is False + needs_inev = not transactionsafe + assert call_descr.extrainfo.call_needs_inevitable() is needs_inev def test_call_release_gil(): from rpython.jit.backend.llgraph.runner import LLGraphCPU diff --git a/rpython/translator/stm/inevitable.py b/rpython/translator/stm/inevitable.py --- a/rpython/translator/stm/inevitable.py +++ b/rpython/translator/stm/inevitable.py @@ -7,7 +7,9 @@ ALWAYS_ALLOW_OPERATIONS = set([ 'force_cast', 'keepalive', 'cast_ptr_to_adr', 'cast_adr_to_int', - 'debug_print', 'debug_assert', 'cast_opaque_ptr', 'hint', + 'debug_print', 'debug_assert', + 'debug_start', 'debug_stop', 'have_debug_prints', + 'cast_opaque_ptr', 'hint', 'stack_current', 'gc_stack_bottom', 'cast_current_ptr_to_int', # this variant of 'cast_ptr_to_int' is ok 'jit_force_virtual', 'jit_force_virtualizable', @@ -53,6 +55,29 @@ return False return not fresh_mallocs.is_fresh_malloc(op.args[0]) +def should_turn_inevitable_call(op): + if op.opname == 'direct_call': + funcptr = op.args[0].value._obj + if not hasattr(funcptr, "external"): + return False + if getattr(funcptr, "transactionsafe", False): + return False + try: + return funcptr._name + '()' + except AttributeError: + return True + + elif op.opname == 'indirect_call': + tographs = op.args[-1].value + if tographs is not None: + # Set of RPython functions + return False + # unknown function + return True + + assert False + + def should_turn_inevitable(op, block, fresh_mallocs): # Always-allowed operations never cause a 'turn inevitable' if op.opname in ALWAYS_ALLOW_OPERATIONS: @@ -80,25 +105,8 @@ return not fresh_mallocs.is_fresh_malloc(op.args[0]) # # Function calls - if op.opname == 'direct_call': - funcptr = op.args[0].value._obj - if not hasattr(funcptr, "external"): - return False - if getattr(funcptr, "transactionsafe", False): - return False - try: - return funcptr._name + '()' - except AttributeError: - return True - - if op.opname == 'indirect_call': - tographs = op.args[-1].value - if tographs is not None: - # Set of RPython functions - return False - # unknown function - return True - + if op.opname == 'direct_call' or op.opname == 'indirect_call': + return should_turn_inevitable_call(op) # # Entirely unsupported operations cause a 'turn inevitable' return True From noreply at buildbot.pypy.org Wed Sep 11 20:06:01 2013 From: noreply at buildbot.pypy.org (Raemi) Date: Wed, 11 Sep 2013 20:06:01 +0200 (CEST) Subject: [pypy-commit] pypy stmgc-c4: merge Message-ID: <20130911180601.8BDFC1C12F0@cobra.cs.uni-duesseldorf.de> Author: Remi Meier Branch: stmgc-c4 Changeset: r66907:abe3019f8ea3 Date: 2013-09-11 20:05 +0200 http://bitbucket.org/pypy/pypy/changeset/abe3019f8ea3/ Log: merge diff --git a/pypy/interpreter/executioncontext.py b/pypy/interpreter/executioncontext.py --- a/pypy/interpreter/executioncontext.py +++ b/pypy/interpreter/executioncontext.py @@ -60,6 +60,7 @@ def enter(self, frame): if self.space.config.translation.stm: + if not self.space.config.translation.jit: # XXX from pypy.module.thread.stm import enter_frame enter_frame(self, frame) frame.f_backref = self.topframeref @@ -87,6 +88,7 @@ self.space.frame_trace_action.fire() if self.space.config.translation.stm: + if not self.space.config.translation.jit: # XXX from pypy.module.thread.stm import leave_frame leave_frame(self, frame) From noreply at buildbot.pypy.org Wed Sep 11 20:26:12 2013 From: noreply at buildbot.pypy.org (arigo) Date: Wed, 11 Sep 2013 20:26:12 +0200 (CEST) Subject: [pypy-commit] stmgc default: Move 'd->active = 0' a bit earlier. This should be enough to ensure the new comment. Message-ID: <20130911182612.9B6721C0165@cobra.cs.uni-duesseldorf.de> Author: Armin Rigo Branch: Changeset: r526:983af03354a5 Date: 2013-09-11 19:52 +0200 http://bitbucket.org/pypy/stmgc/changeset/983af03354a5/ Log: Move 'd->active = 0' a bit earlier. This should be enough to ensure the new comment. diff --git a/c4/et.c b/c4/et.c --- a/c4/et.c +++ b/c4/et.c @@ -982,6 +982,13 @@ stm_thread_local_obj = d->old_thread_local_obj; d->old_thread_local_obj = NULL; + // notifies the CPU that we're potentially in a spin loop + SpinLoop(SPLP_ABORT); + + /* make the transaction no longer active */ + d->active = 0; + d->atomic = 0; + /* release the lock */ spinlock_release(d->public_descriptor->collection_lock); @@ -1003,11 +1010,7 @@ if (num != ABRT_MANUAL && d->max_aborts >= 0 && !d->max_aborts--) stm_fatalerror("unexpected abort!\n"); - // notifies the CPU that we're potentially in a spin loop - SpinLoop(SPLP_ABORT); // jump back to the setjmp_buf (this call does not return) - d->active = 0; - d->atomic = 0; stm_stop_sharedlock(); longjmp(*d->setjmp_buf, 1); } diff --git a/c4/extra.c b/c4/extra.c --- a/c4/extra.c +++ b/c4/extra.c @@ -48,12 +48,16 @@ void stm_invoke_callbacks_on_abort(struct tx_descriptor *d) { wlog_t *item; + assert(d->active == 0); + G2L_LOOP_FORWARD(d->callbacks_on_abort, item) { void *key = (void *)item->addr; void (*callback)(void *) = (void(*)(void *))item->val; assert(key != NULL); assert(callback != NULL); + /* The callback may call stm_call_on_abort(key, NULL). + It is ignored, because we're no longer active. */ callback(key); } G2L_LOOP_END; From noreply at buildbot.pypy.org Wed Sep 11 20:26:13 2013 From: noreply at buildbot.pypy.org (arigo) Date: Wed, 11 Sep 2013 20:26:13 +0200 (CEST) Subject: [pypy-commit] stmgc default: I *think* this is what is needed Message-ID: <20130911182613.A3A0A1C0165@cobra.cs.uni-duesseldorf.de> Author: Armin Rigo Branch: Changeset: r527:c5636881b4d5 Date: 2013-09-11 20:26 +0200 http://bitbucket.org/pypy/stmgc/changeset/c5636881b4d5/ Log: I *think* this is what is needed diff --git a/c4/stmsync.c b/c4/stmsync.c --- a/c4/stmsync.c +++ b/c4/stmsync.c @@ -218,6 +218,8 @@ struct tx_descriptor *d = thread_descriptor; if (!d->atomic) CommitTransaction(); + else + BecomeInevitable("stm_commit_transaction but atomic"); } void stm_begin_inevitable_transaction(void) From noreply at buildbot.pypy.org Wed Sep 11 20:27:30 2013 From: noreply at buildbot.pypy.org (arigo) Date: Wed, 11 Sep 2013 20:27:30 +0200 (CEST) Subject: [pypy-commit] pypy stmgc-c4: import stmgc/983af03354a5 Message-ID: <20130911182730.224AD1C0165@cobra.cs.uni-duesseldorf.de> Author: Armin Rigo Branch: stmgc-c4 Changeset: r66908:f2c9e61af458 Date: 2013-09-11 19:56 +0200 http://bitbucket.org/pypy/pypy/changeset/f2c9e61af458/ Log: import stmgc/983af03354a5 diff --git a/rpython/translator/stm/src_stm/et.c b/rpython/translator/stm/src_stm/et.c --- a/rpython/translator/stm/src_stm/et.c +++ b/rpython/translator/stm/src_stm/et.c @@ -983,6 +983,13 @@ stm_thread_local_obj = d->old_thread_local_obj; d->old_thread_local_obj = NULL; + // notifies the CPU that we're potentially in a spin loop + SpinLoop(SPLP_ABORT); + + /* make the transaction no longer active */ + d->active = 0; + d->atomic = 0; + /* release the lock */ spinlock_release(d->public_descriptor->collection_lock); @@ -1004,11 +1011,7 @@ if (num != ABRT_MANUAL && d->max_aborts >= 0 && !d->max_aborts--) stm_fatalerror("unexpected abort!\n"); - // notifies the CPU that we're potentially in a spin loop - SpinLoop(SPLP_ABORT); // jump back to the setjmp_buf (this call does not return) - d->active = 0; - d->atomic = 0; stm_stop_sharedlock(); longjmp(*d->setjmp_buf, 1); } diff --git a/rpython/translator/stm/src_stm/extra.c b/rpython/translator/stm/src_stm/extra.c --- a/rpython/translator/stm/src_stm/extra.c +++ b/rpython/translator/stm/src_stm/extra.c @@ -49,12 +49,16 @@ void stm_invoke_callbacks_on_abort(struct tx_descriptor *d) { wlog_t *item; + assert(d->active == 0); + G2L_LOOP_FORWARD(d->callbacks_on_abort, item) { void *key = (void *)item->addr; void (*callback)(void *) = (void(*)(void *))item->val; assert(key != NULL); assert(callback != NULL); + /* The callback may call stm_call_on_abort(key, NULL). + It is ignored, because we're no longer active. */ callback(key); } G2L_LOOP_END; diff --git a/rpython/translator/stm/src_stm/revision b/rpython/translator/stm/src_stm/revision --- a/rpython/translator/stm/src_stm/revision +++ b/rpython/translator/stm/src_stm/revision @@ -1,1 +1,1 @@ -698910c9edc3 +983af03354a5 From noreply at buildbot.pypy.org Wed Sep 11 20:27:31 2013 From: noreply at buildbot.pypy.org (arigo) Date: Wed, 11 Sep 2013 20:27:31 +0200 (CEST) Subject: [pypy-commit] pypy stmgc-c4: Fix dtoa.c to use stm_call_on_abort(), which makes the code transactionsafe again. Message-ID: <20130911182731.5E3801C0165@cobra.cs.uni-duesseldorf.de> Author: Armin Rigo Branch: stmgc-c4 Changeset: r66909:4f180feddf69 Date: 2013-09-11 19:57 +0200 http://bitbucket.org/pypy/pypy/changeset/4f180feddf69/ Log: Fix dtoa.c to use stm_call_on_abort(), which makes the code transactionsafe again. diff --git a/rpython/rlib/rdtoa.py b/rpython/rlib/rdtoa.py --- a/rpython/rlib/rdtoa.py +++ b/rpython/rlib/rdtoa.py @@ -40,17 +40,16 @@ dg_strtod = rffi.llexternal( '_PyPy_dg_strtod', [rffi.CCHARP, rffi.CCHARPP], rffi.DOUBLE, - compilation_info=eci, sandboxsafe=True, - transactionsafe=True) + compilation_info=eci, sandboxsafe=True, transactionsafe=True) dg_dtoa = rffi.llexternal( '_PyPy_dg_dtoa', [rffi.DOUBLE, rffi.INT, rffi.INT, rffi.INTP, rffi.INTP, rffi.CCHARPP], rffi.CCHARP, - compilation_info=eci, sandboxsafe=True) + compilation_info=eci, sandboxsafe=True, transactionsafe=True) dg_freedtoa = rffi.llexternal( '_PyPy_dg_freedtoa', [rffi.CCHARP], lltype.Void, - compilation_info=eci, sandboxsafe=True) + compilation_info=eci, sandboxsafe=True, transactionsafe=True) def strtod(input): ll_input = rffi.str2charp(input) diff --git a/rpython/translator/c/src/dtoa.c b/rpython/translator/c/src/dtoa.c --- a/rpython/translator/c/src/dtoa.c +++ b/rpython/translator/c/src/dtoa.c @@ -325,11 +325,13 @@ typedef struct Bigint Bigint; +#ifdef RPY_STM #define Py_USING_MEMORY_DEBUGGER /* Set to use thread-safe malloc, free */ #undef MALLOC #undef FREE #define MALLOC malloc /* use thread-safe malloc/free */ #define FREE free +#endif #ifndef Py_USING_MEMORY_DEBUGGER @@ -2966,11 +2968,17 @@ _PyPy_SET_53BIT_PRECISION_START; result = __Py_dg_dtoa(dd, mode, ndigits, decpt, sign, rve); _PyPy_SET_53BIT_PRECISION_END; +#ifdef RPY_STM + stm_call_on_abort(result, _PyPy_dg_freedtoa); +#endif return result; } void _PyPy_dg_freedtoa(char *s) { +#ifdef RPY_STM + stm_call_on_abort(s, NULL); +#endif __Py_dg_freedtoa(s); } /* End PYPY hacks */ diff --git a/rpython/translator/stm/test/test_ztranslated.py b/rpython/translator/stm/test/test_ztranslated.py --- a/rpython/translator/stm/test/test_ztranslated.py +++ b/rpython/translator/stm/test/test_ztranslated.py @@ -376,3 +376,17 @@ data, dataerr = cbuilder.cmdexec('', err=True) lines = dataerr.split('\n') assert lines[0] == lines[1] + + def test_dtoa(self): + def main(argv): + a = len(argv) * 0.2 + b = len(argv) * 0.6 + debug_print(str(a)) + debug_print(str(b)) + return 0 + + t, cbuilder = self.compile(main) + data, dataerr = cbuilder.cmdexec('a', err=True) + lines = dataerr.split('\n') + assert lines[0] == ' 0.400000' + assert lines[1] == ' 1.200000' From noreply at buildbot.pypy.org Wed Sep 11 20:27:32 2013 From: noreply at buildbot.pypy.org (arigo) Date: Wed, 11 Sep 2013 20:27:32 +0200 (CEST) Subject: [pypy-commit] pypy stmgc-c4: merge heads Message-ID: <20130911182732.8006D1C0165@cobra.cs.uni-duesseldorf.de> Author: Armin Rigo Branch: stmgc-c4 Changeset: r66910:4c548ac9cced Date: 2013-09-11 20:17 +0200 http://bitbucket.org/pypy/pypy/changeset/4c548ac9cced/ Log: merge heads 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 @@ -404,12 +404,27 @@ category = 'i' else: assert 0 - source = py.code.Source(""" - def call_stub(func, args_i, args_r, args_f): - fnptr = rffi.cast(lltype.Ptr(FUNC), func) - res = support.maybe_on_top_of_llinterp(rtyper, fnptr)(%(args)s) - return %(result)s - """ % locals()) + + llop1 = llop + if not stm or ( + self.extrainfo and self.extrainfo.call_needs_inevitable()): + source = py.code.Source(""" + def call_stub(func, args_i, args_r, args_f): + fnptr = rffi.cast(lltype.Ptr(FUNC), func) + res = support.maybe_on_top_of_llinterp(rtyper, fnptr)(%(args)s) + return %(result)s + """ % locals()) + else: + # the above 'source' works on STM too, but always forces + # the transaction to become inevitable. Using jit_assembler_call + # in cases where it is not needed avoids that. + source = py.code.Source(""" + def call_stub(func, args_i, args_r, args_f): + fnptr = rffi.cast(lltype.Ptr(FUNC), func) + fun = support.maybe_on_top_of_llinterp(rtyper, fnptr) + res = llop1.jit_assembler_call(RESULT, fun, %(args)s) + return %(result)s + """ % locals()) ARGS = [TYPE(arg) for arg in self.arg_classes] FUNC = lltype.FuncType(ARGS, RESULT) d = globals().copy() diff --git a/rpython/jit/backend/llsupport/stmrewrite.py b/rpython/jit/backend/llsupport/stmrewrite.py --- a/rpython/jit/backend/llsupport/stmrewrite.py +++ b/rpython/jit/backend/llsupport/stmrewrite.py @@ -1,4 +1,5 @@ from rpython.jit.backend.llsupport.rewrite import GcRewriterAssembler +from rpython.jit.backend.llsupport.descr import CallDescr from rpython.jit.metainterp.resoperation import ResOperation, rop from rpython.jit.metainterp.history import BoxPtr, ConstPtr, ConstInt from rpython.rlib.objectmodel import specialize @@ -108,7 +109,13 @@ elif op.getopnum() == rop.CALL_ASSEMBLER: self.handle_call_assembler(op) else: - self.newops.append(op) + descr = op.getdescr() + assert not descr or isinstance(descr, CallDescr) + if descr and descr.get_extra_info() and \ + descr.get_extra_info().call_needs_inevitable(): + self.fallback_inevitable(op) + else: + self.newops.append(op) self.known_category.clear() continue # ---------- copystrcontent ---------- diff --git a/rpython/jit/backend/llsupport/test/test_descr.py b/rpython/jit/backend/llsupport/test/test_descr.py --- a/rpython/jit/backend/llsupport/test/test_descr.py +++ b/rpython/jit/backend/llsupport/test/test_descr.py @@ -353,6 +353,32 @@ descr5f = get_call_descr(c0, [lltype.Char], lltype.SingleFloat) assert repr_of_descr(descr5f) == '' + +def test_call_stubs_inevitable(): + for inev in (True, False): + class fakeextrainfo: + def call_needs_inevitable(self): + return inev + class fakertyper: + class annotator: + class translator: + class config: + class translation: + stm = True + + c0 = GcCache(False, rtyper=fakertyper()) + ARGS = [lltype.Char, lltype.Signed] + RES = lltype.Char + descr1 = get_call_descr(c0, ARGS, RES, extrainfo=fakeextrainfo()) + def f(a, b): + return 'c' + + fnptr = llhelper(lltype.Ptr(lltype.FuncType(ARGS, RES)), f) + + res = descr1.call_stub_i(rffi.cast(lltype.Signed, fnptr), + [1, 2], None, None) + assert res == ord('c') + def test_call_stubs_1(): c0 = GcCache(False) ARGS = [lltype.Char, lltype.Signed] diff --git a/rpython/jit/backend/llsupport/test/test_stmrewrite.py b/rpython/jit/backend/llsupport/test/test_stmrewrite.py --- a/rpython/jit/backend/llsupport/test/test_stmrewrite.py +++ b/rpython/jit/backend/llsupport/test/test_stmrewrite.py @@ -62,6 +62,29 @@ RewriteTests.check_rewrite(self, frm_operations, to_operations, **namespace) + def test_inevitable_calls(self): + c1 = GcCache(True) + T = lltype.GcStruct('T') + U = lltype.GcStruct('U', ('x', lltype.Signed)) + for inev in (True, False): + class fakeextrainfo: + def call_needs_inevitable(self): + return inev + + calldescr = get_call_descr(c1, [lltype.Ptr(T)], lltype.Ptr(U), + fakeextrainfo()) + + self.check_rewrite(""" + [] + call(123, descr=cd) + jump() + """,""" + [] + %s + call(123, descr=cd) + jump() + """ % ("$INEV" if inev else "",), cd=calldescr) + def test_rewrite_one_setfield_gc(self): self.check_rewrite(""" [p1, p2] diff --git a/rpython/jit/codewriter/call.py b/rpython/jit/codewriter/call.py --- a/rpython/jit/codewriter/call.py +++ b/rpython/jit/codewriter/call.py @@ -196,6 +196,12 @@ elidable = False loopinvariant = False call_release_gil_target = llmemory.NULL + needs_inevitable = False + if op.opname == 'indirect_call' or op.opname == 'direct_call': + from rpython.translator.stm.inevitable import ( + should_turn_inevitable_call) + needs_inevitable = bool(should_turn_inevitable_call(op)) + if op.opname == "direct_call": funcobj = op.args[0].value._obj assert getattr(funcobj, 'calling_conv', 'c') == 'c', ( @@ -206,7 +212,8 @@ if loopinvariant: assert not NON_VOID_ARGS, ("arguments not supported for " "loop-invariant function!") - if getattr(func, "_call_aroundstate_target_", None): + funcptr = getattr(func, "_call_aroundstate_target_", None) + if funcptr: call_release_gil_target = func._call_aroundstate_target_ call_release_gil_target = llmemory.cast_ptr_to_adr( call_release_gil_target) @@ -234,6 +241,7 @@ effectinfo = effectinfo_from_writeanalyze( self.readwrite_analyzer.analyze(op), self.cpu, extraeffect, oopspecindex, can_invalidate, call_release_gil_target, + needs_inevitable ) # assert effectinfo is not None 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 @@ -96,14 +96,16 @@ extraeffect=EF_CAN_RAISE, oopspecindex=OS_NONE, can_invalidate=False, - call_release_gil_target=llmemory.NULL): + call_release_gil_target=llmemory.NULL, + needs_inevitable=False): key = (frozenset_or_none(readonly_descrs_fields), frozenset_or_none(readonly_descrs_arrays), frozenset_or_none(write_descrs_fields), frozenset_or_none(write_descrs_arrays), extraeffect, oopspecindex, - can_invalidate) + can_invalidate, + needs_inevitable) if call_release_gil_target: key += (object(),) # don't care about caching in this case if key in cls._cache: @@ -131,6 +133,7 @@ result.write_descrs_arrays = write_descrs_arrays result.extraeffect = extraeffect result.can_invalidate = can_invalidate + result.needs_inevitable = needs_inevitable result.oopspecindex = oopspecindex result.call_release_gil_target = call_release_gil_target if result.check_can_raise(): @@ -157,6 +160,9 @@ def is_call_release_gil(self): return bool(self.call_release_gil_target) + def call_needs_inevitable(self): + return self.needs_inevitable + def frozenset_or_none(x): if x is None: @@ -172,7 +178,8 @@ extraeffect=EffectInfo.EF_CAN_RAISE, oopspecindex=EffectInfo.OS_NONE, can_invalidate=False, - call_release_gil_target=llmemory.NULL): + call_release_gil_target=llmemory.NULL, + needs_inevitable=False): from rpython.translator.backendopt.writeanalyze import top_set if effects is top_set or extraeffect == EffectInfo.EF_RANDOM_EFFECTS: readonly_descrs_fields = None @@ -221,7 +228,8 @@ extraeffect, oopspecindex, can_invalidate, - call_release_gil_target) + call_release_gil_target, + needs_inevitable) def consider_struct(TYPE, fieldname): if fieldType(TYPE, fieldname) is lltype.Void: 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 @@ -198,6 +198,33 @@ call_descr = cc.getcalldescr(op) assert call_descr.extrainfo.has_random_effects() assert call_descr.extrainfo.is_call_release_gil() is False + assert call_descr.extrainfo.call_needs_inevitable() is False + +def test_releases_gil_analyzer_needs_inevitable(): + from rpython.jit.backend.llgraph.runner import LLGraphCPU + + for transactionsafe in (True, False): + T = rffi.CArrayPtr(rffi.TIME_T) + external = rffi.llexternal("time", [T], rffi.TIME_T, + _nowrapper=True, + threadsafe=False, + transactionsafe=transactionsafe) + + @jit.dont_look_inside + def f(): + return external(lltype.nullptr(T.TO)) + + rtyper = support.annotate(f, []) + jitdriver_sd = FakeJitDriverSD(rtyper.annotator.translator.graphs[0]) + cc = CallControl(LLGraphCPU(rtyper), jitdrivers_sd=[jitdriver_sd]) + res = cc.find_all_graphs(FakePolicy()) + [f_graph] = [x for x in res if x.func is f] + [block, _] = list(f_graph.iterblocks()) + [op] = block.operations + call_descr = cc.getcalldescr(op) + assert call_descr.extrainfo.is_call_release_gil() is False + needs_inev = not transactionsafe + assert call_descr.extrainfo.call_needs_inevitable() is needs_inev def test_call_release_gil(): from rpython.jit.backend.llgraph.runner import LLGraphCPU diff --git a/rpython/translator/stm/inevitable.py b/rpython/translator/stm/inevitable.py --- a/rpython/translator/stm/inevitable.py +++ b/rpython/translator/stm/inevitable.py @@ -7,7 +7,9 @@ ALWAYS_ALLOW_OPERATIONS = set([ 'force_cast', 'keepalive', 'cast_ptr_to_adr', 'cast_adr_to_int', - 'debug_print', 'debug_assert', 'cast_opaque_ptr', 'hint', + 'debug_print', 'debug_assert', + 'debug_start', 'debug_stop', 'have_debug_prints', + 'cast_opaque_ptr', 'hint', 'stack_current', 'gc_stack_bottom', 'cast_current_ptr_to_int', # this variant of 'cast_ptr_to_int' is ok 'jit_force_virtual', 'jit_force_virtualizable', @@ -53,6 +55,29 @@ return False return not fresh_mallocs.is_fresh_malloc(op.args[0]) +def should_turn_inevitable_call(op): + if op.opname == 'direct_call': + funcptr = op.args[0].value._obj + if not hasattr(funcptr, "external"): + return False + if getattr(funcptr, "transactionsafe", False): + return False + try: + return funcptr._name + '()' + except AttributeError: + return True + + elif op.opname == 'indirect_call': + tographs = op.args[-1].value + if tographs is not None: + # Set of RPython functions + return False + # unknown function + return True + + assert False + + def should_turn_inevitable(op, block, fresh_mallocs): # Always-allowed operations never cause a 'turn inevitable' if op.opname in ALWAYS_ALLOW_OPERATIONS: @@ -80,25 +105,8 @@ return not fresh_mallocs.is_fresh_malloc(op.args[0]) # # Function calls - if op.opname == 'direct_call': - funcptr = op.args[0].value._obj - if not hasattr(funcptr, "external"): - return False - if getattr(funcptr, "transactionsafe", False): - return False - try: - return funcptr._name + '()' - except AttributeError: - return True - - if op.opname == 'indirect_call': - tographs = op.args[-1].value - if tographs is not None: - # Set of RPython functions - return False - # unknown function - return True - + if op.opname == 'direct_call' or op.opname == 'indirect_call': + return should_turn_inevitable_call(op) # # Entirely unsupported operations cause a 'turn inevitable' return True From noreply at buildbot.pypy.org Wed Sep 11 20:27:33 2013 From: noreply at buildbot.pypy.org (arigo) Date: Wed, 11 Sep 2013 20:27:33 +0200 (CEST) Subject: [pypy-commit] pypy stmgc-c4: import stmgc/c5636881b4d5 Message-ID: <20130911182733.A49111C0165@cobra.cs.uni-duesseldorf.de> Author: Armin Rigo Branch: stmgc-c4 Changeset: r66911:0b21653c6034 Date: 2013-09-11 20:26 +0200 http://bitbucket.org/pypy/pypy/changeset/0b21653c6034/ Log: import stmgc/c5636881b4d5 diff --git a/rpython/translator/stm/src_stm/et.c b/rpython/translator/stm/src_stm/et.c --- a/rpython/translator/stm/src_stm/et.c +++ b/rpython/translator/stm/src_stm/et.c @@ -1534,8 +1534,8 @@ (XXX statically we should know when we're outside a transaction) */ - fprintf(stderr, "[%lx] inevitable: %s\n", - (long)d->public_descriptor_index, why); + dprintf(("[%lx] inevitable: %s\n", + (long)d->public_descriptor_index, why)); cur_time = acquire_inev_mutex_and_mark_global_cur_time(d); if (d->start_time != cur_time) diff --git a/rpython/translator/stm/src_stm/revision b/rpython/translator/stm/src_stm/revision --- a/rpython/translator/stm/src_stm/revision +++ b/rpython/translator/stm/src_stm/revision @@ -1,1 +1,1 @@ -983af03354a5 +c5636881b4d5 diff --git a/rpython/translator/stm/src_stm/stmsync.c b/rpython/translator/stm/src_stm/stmsync.c --- a/rpython/translator/stm/src_stm/stmsync.c +++ b/rpython/translator/stm/src_stm/stmsync.c @@ -219,6 +219,8 @@ struct tx_descriptor *d = thread_descriptor; if (!d->atomic) CommitTransaction(); + else + BecomeInevitable("stm_commit_transaction but atomic"); } void stm_begin_inevitable_transaction(void) From noreply at buildbot.pypy.org Wed Sep 11 20:27:34 2013 From: noreply at buildbot.pypy.org (arigo) Date: Wed, 11 Sep 2013 20:27:34 +0200 (CEST) Subject: [pypy-commit] pypy stmgc-c4: Fix the test Message-ID: <20130911182734.BC9481C0165@cobra.cs.uni-duesseldorf.de> Author: Armin Rigo Branch: stmgc-c4 Changeset: r66912:27e74b97ecf6 Date: 2013-09-11 20:26 +0200 http://bitbucket.org/pypy/pypy/changeset/27e74b97ecf6/ Log: Fix the test 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 @@ -200,14 +200,14 @@ assert call_descr.extrainfo.is_call_release_gil() is False assert call_descr.extrainfo.call_needs_inevitable() is False -def test_releases_gil_analyzer_needs_inevitable(): +def test_call_needs_inevitable(): from rpython.jit.backend.llgraph.runner import LLGraphCPU for transactionsafe in (True, False): T = rffi.CArrayPtr(rffi.TIME_T) external = rffi.llexternal("time", [T], rffi.TIME_T, _nowrapper=True, - threadsafe=False, + threadsafe=True, transactionsafe=transactionsafe) @jit.dont_look_inside From noreply at buildbot.pypy.org Wed Sep 11 20:28:45 2013 From: noreply at buildbot.pypy.org (arigo) Date: Wed, 11 Sep 2013 20:28:45 +0200 (CEST) Subject: [pypy-commit] pypy stmgc-c4: Redo this hack Message-ID: <20130911182845.81A8D1C0165@cobra.cs.uni-duesseldorf.de> Author: Armin Rigo Branch: stmgc-c4 Changeset: r66913:681d74703a22 Date: 2013-09-11 20:28 +0200 http://bitbucket.org/pypy/pypy/changeset/681d74703a22/ Log: Redo this hack diff --git a/rpython/translator/stm/src_stm/et.c b/rpython/translator/stm/src_stm/et.c --- a/rpython/translator/stm/src_stm/et.c +++ b/rpython/translator/stm/src_stm/et.c @@ -1534,8 +1534,8 @@ (XXX statically we should know when we're outside a transaction) */ - dprintf(("[%lx] inevitable: %s\n", - (long)d->public_descriptor_index, why)); + fprintf(stderr, "[%lx] inevitable: %s\n", + (long)d->public_descriptor_index, why); cur_time = acquire_inev_mutex_and_mark_global_cur_time(d); if (d->start_time != cur_time) From noreply at buildbot.pypy.org Wed Sep 11 20:36:25 2013 From: noreply at buildbot.pypy.org (arigo) Date: Wed, 11 Sep 2013 20:36:25 +0200 (CEST) Subject: [pypy-commit] pypy stmgc-c4: Argh, thanks Remi. We're going to rename this obscure name. Message-ID: <20130911183625.A5A511C02DE@cobra.cs.uni-duesseldorf.de> Author: Armin Rigo Branch: stmgc-c4 Changeset: r66914:555ebb4f400f Date: 2013-09-11 20:35 +0200 http://bitbucket.org/pypy/pypy/changeset/555ebb4f400f/ Log: Argh, thanks Remi. We're going to rename this obscure name. 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 @@ -207,7 +207,7 @@ T = rffi.CArrayPtr(rffi.TIME_T) external = rffi.llexternal("time", [T], rffi.TIME_T, _nowrapper=True, - threadsafe=True, + threadsafe=False, transactionsafe=transactionsafe) @jit.dont_look_inside From noreply at buildbot.pypy.org Wed Sep 11 20:40:59 2013 From: noreply at buildbot.pypy.org (Raemi) Date: Wed, 11 Sep 2013 20:40:59 +0200 (CEST) Subject: [pypy-commit] pypy stmgc-c4: 2 more tests just to be sure Message-ID: <20130911184059.3A0981C02DE@cobra.cs.uni-duesseldorf.de> Author: Remi Meier Branch: stmgc-c4 Changeset: r66915:bf4114ba9364 Date: 2013-09-11 20:39 +0200 http://bitbucket.org/pypy/pypy/changeset/bf4114ba9364/ Log: 2 more tests just to be sure 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 @@ -226,6 +226,51 @@ needs_inev = not transactionsafe assert call_descr.extrainfo.call_needs_inevitable() is needs_inev +def test_call_needs_not_inevitable(): + from rpython.jit.backend.llgraph.runner import LLGraphCPU + + def g(): + pass + + @jit.dont_look_inside + def f(): + return g() + + rtyper = support.annotate(f, []) + jitdriver_sd = FakeJitDriverSD(rtyper.annotator.translator.graphs[0]) + cc = CallControl(LLGraphCPU(rtyper), jitdrivers_sd=[jitdriver_sd]) + res = cc.find_all_graphs(FakePolicy()) + [f_graph] = [x for x in res if x.func is f] + [block, _] = list(f_graph.iterblocks()) + [op] = block.operations + call_descr = cc.getcalldescr(op) + + assert call_descr.extrainfo.call_needs_inevitable() is False + +def test_call_needs_not_inevitable2(): + from rpython.jit.backend.llgraph.runner import LLGraphCPU + + def g(): + pass + def u(): + pass + funcs = [g, u] + @jit.dont_look_inside + def f(i): + return funcs[i]() + + rtyper = support.annotate(f, [1]) + jitdriver_sd = FakeJitDriverSD(rtyper.annotator.translator.graphs[0]) + cc = CallControl(LLGraphCPU(rtyper), jitdrivers_sd=[jitdriver_sd]) + res = cc.find_all_graphs(FakePolicy()) + [f_graph] = [x for x in res if x.func is f] + [block, _] = list(f_graph.iterblocks()) + [_, op] = block.operations + call_descr = cc.getcalldescr(op) + + assert call_descr.extrainfo.call_needs_inevitable() is False + + def test_call_release_gil(): from rpython.jit.backend.llgraph.runner import LLGraphCPU From noreply at buildbot.pypy.org Wed Sep 11 20:55:45 2013 From: noreply at buildbot.pypy.org (mattip) Date: Wed, 11 Sep 2013 20:55:45 +0200 (CEST) Subject: [pypy-commit] pypy pypy-pyarray: graft changeset 0e2f0d910e8f onto branch (test and Fix for None as rdict key) Message-ID: <20130911185545.CA25F1C02DE@cobra.cs.uni-duesseldorf.de> Author: Matti Picus Branch: pypy-pyarray Changeset: r66916:ec6ab79a192c Date: 2013-09-09 23:04 +0300 http://bitbucket.org/pypy/pypy/changeset/ec6ab79a192c/ Log: graft changeset 0e2f0d910e8f onto branch (test and Fix for None as rdict key) diff --git a/rpython/rtyper/rpbc.py b/rpython/rtyper/rpbc.py --- a/rpython/rtyper/rpbc.py +++ b/rpython/rtyper/rpbc.py @@ -594,6 +594,9 @@ def ll_str(self, none): return llstr("None") + def get_ll_eq_function(self): + return None + def get_ll_hash_function(self): return ll_none_hash diff --git a/rpython/rtyper/test/test_rdict.py b/rpython/rtyper/test/test_rdict.py --- a/rpython/rtyper/test/test_rdict.py +++ b/rpython/rtyper/test/test_rdict.py @@ -1051,6 +1051,13 @@ finally: lltype._array._check_range = original_check_range + def test_dict_with_none_key(self): + def func(i): + d = {None: i} + return d[None] + res = self.interpret(func, [42]) + assert res == 42 + class TestStress: From noreply at buildbot.pypy.org Wed Sep 11 20:55:47 2013 From: noreply at buildbot.pypy.org (mattip) Date: Wed, 11 Sep 2013 20:55:47 +0200 (CEST) Subject: [pypy-commit] pypy pypy-pyarray: change wrap/unwrap to rffi.cast as per review comments Message-ID: <20130911185547.0BA231C02DE@cobra.cs.uni-duesseldorf.de> Author: Matti Picus Branch: pypy-pyarray Changeset: r66917:ef2bc6827618 Date: 2013-09-11 21:54 +0300 http://bitbucket.org/pypy/pypy/changeset/ef2bc6827618/ Log: change wrap/unwrap to rffi.cast as per review comments diff --git a/TODO.txt b/TODO.txt --- a/TODO.txt +++ b/TODO.txt @@ -4,15 +4,6 @@ - why do we need to implement array.nonzero on this branch and it was not done e.g. on default? -- def get_shape_and_dtype(space, nd, dims, typenum): - shape = [] - for i in range(nd): - # back-and-forth wrapping needed to translate - shape.append(space.int_w(space.wrap(dims[i]))) - - this looks very strange: we should probably do a proper rpython cast instead - of doing this strange wrap/unwrap dance - - interp_numarray.py :: descr___array__: the dtype method is ignored: it's fine to have a half-working implementation, but it should raise an exception if it's passed diff --git a/pypy/module/cpyext/ndarrayobject.py b/pypy/module/cpyext/ndarrayobject.py --- a/pypy/module/cpyext/ndarrayobject.py +++ b/pypy/module/cpyext/ndarrayobject.py @@ -187,8 +187,7 @@ def get_shape_and_dtype(space, nd, dims, typenum): shape = [] for i in range(nd): - # back-and-forth wrapping needed to translate - shape.append(space.int_w(space.wrap(dims[i]))) + shape.append(rffi.cast(rffi.LONG, dims[i])) dtype = get_dtype_cache(space).dtypes_by_num[typenum] return shape, dtype From noreply at buildbot.pypy.org Wed Sep 11 21:47:26 2013 From: noreply at buildbot.pypy.org (arigo) Date: Wed, 11 Sep 2013 21:47:26 +0200 (CEST) Subject: [pypy-commit] stmgc default: Support non-aligned keys in g2l_insert(), as needed for Message-ID: <20130911194726.C9F0C1C0929@cobra.cs.uni-duesseldorf.de> Author: Armin Rigo Branch: Changeset: r528:0b3f7830cb46 Date: 2013-09-11 21:46 +0200 http://bitbucket.org/pypy/stmgc/changeset/0b3f7830cb46/ Log: Support non-aligned keys in g2l_insert(), as needed for stm_call_on_abort(). diff --git a/c4/lists.c b/c4/lists.c --- a/c4/lists.c +++ b/c4/lists.c @@ -90,7 +90,6 @@ int shift = 0; char *p = (char *)(g2l->toplevel.items); char *entry; - assert((key & (sizeof(void*)-1)) == 0); /* only for aligned keys */ while (1) { p += (key >> shift) & TREE_MASK; diff --git a/c4/test/test_extra.py b/c4/test/test_extra.py --- a/c4/test/test_extra.py +++ b/c4/test/test_extra.py @@ -292,7 +292,7 @@ if retry_counter == 0: lib.stm_call_on_abort(p1, clear_me) lib.stm_call_on_abort(p2, clear_me) - lib.stm_call_on_abort(p3, clear_me) + lib.stm_call_on_abort(p3 + 1, clear_me) lib.stm_call_on_abort(p2, ffi.NULL) # assert ffi.string(p0) == "aaa" @@ -303,7 +303,7 @@ abort_and_retry() else: assert ffi.string(p1) == "iello" - assert ffi.string(p3) == "xorld" + assert ffi.string(p3) == "wprld" if retry_counter == 1: # the registered callbacks are removed # on abort From noreply at buildbot.pypy.org Wed Sep 11 21:48:13 2013 From: noreply at buildbot.pypy.org (arigo) Date: Wed, 11 Sep 2013 21:48:13 +0200 (CEST) Subject: [pypy-commit] pypy stmgc-c4: import stmgc/0b3f7830cb46 Message-ID: <20130911194813.0E93C1C0929@cobra.cs.uni-duesseldorf.de> Author: Armin Rigo Branch: stmgc-c4 Changeset: r66918:7a0291d8cc4b Date: 2013-09-11 21:47 +0200 http://bitbucket.org/pypy/pypy/changeset/7a0291d8cc4b/ Log: import stmgc/0b3f7830cb46 diff --git a/rpython/translator/stm/src_stm/lists.c b/rpython/translator/stm/src_stm/lists.c --- a/rpython/translator/stm/src_stm/lists.c +++ b/rpython/translator/stm/src_stm/lists.c @@ -91,7 +91,6 @@ int shift = 0; char *p = (char *)(g2l->toplevel.items); char *entry; - assert((key & (sizeof(void*)-1)) == 0); /* only for aligned keys */ while (1) { p += (key >> shift) & TREE_MASK; diff --git a/rpython/translator/stm/src_stm/revision b/rpython/translator/stm/src_stm/revision --- a/rpython/translator/stm/src_stm/revision +++ b/rpython/translator/stm/src_stm/revision @@ -1,1 +1,1 @@ -c5636881b4d5 +0b3f7830cb46 From noreply at buildbot.pypy.org Thu Sep 12 00:25:42 2013 From: noreply at buildbot.pypy.org (pjenvey) Date: Thu, 12 Sep 2013 00:25:42 +0200 (CEST) Subject: [pypy-commit] pypy py3k: merge default Message-ID: <20130911222542.EEE011C0165@cobra.cs.uni-duesseldorf.de> Author: Philip Jenvey Branch: py3k Changeset: r66919:f1e02da40fe0 Date: 2013-09-10 11:19 -0700 http://bitbucket.org/pypy/pypy/changeset/f1e02da40fe0/ Log: merge default 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 @@ -418,7 +418,6 @@ bh_setfield_raw = bh_setfield_gc bh_setfield_raw_i = bh_setfield_raw - bh_setfield_raw_r = bh_setfield_raw bh_setfield_raw_f = bh_setfield_raw def bh_arraylen_gc(self, a, descr): 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 @@ -64,8 +64,6 @@ return True def initialize(self): pass - def do_write_barrier(self, gcref_struct, gcref_newptr): - pass def can_use_nursery_malloc(self, size): return False def has_write_barrier_class(self): @@ -135,9 +133,7 @@ def malloc_jitframe(self, frame_info): """ Allocate a new frame, overwritten by tests """ - frame = jitframe.JITFRAME.allocate(frame_info) - llop.gc_writebarrier(lltype.Void, frame) - return frame + return jitframe.JITFRAME.allocate(frame_info) class JitFrameDescrs: def _freeze_(self): @@ -547,17 +543,6 @@ hdr = llmemory.cast_adr_to_ptr(hdr_addr, self.HDRPTR) hdr.tid = tid - def do_write_barrier(self, gcref_struct, gcref_newptr): - hdr_addr = llmemory.cast_ptr_to_adr(gcref_struct) - hdr_addr -= self.gcheaderbuilder.size_gc_header - hdr = llmemory.cast_adr_to_ptr(hdr_addr, self.HDRPTR) - if hdr.tid & self.GCClass.JIT_WB_IF_FLAG: - # get a pointer to the 'remember_young_pointer' function from - # the GC, and call it immediately - llop1 = self.llop1 - funcptr = llop1.get_write_barrier_failing_case(self.WB_FUNCPTR) - funcptr(llmemory.cast_ptr_to_adr(gcref_struct)) - def can_use_nursery_malloc(self, size): return size < self.max_size_of_young_obj 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 @@ -247,6 +247,7 @@ else: assert kind == history.REF self.set_ref_value(ll_frame, num, arg) + llop.gc_writebarrier(lltype.Void, ll_frame) ll_frame = func(ll_frame) finally: if not self.translate_support_code: @@ -390,9 +391,11 @@ else: raise NotImplementedError("size = %d" % size) + @specialize.argtype(1) def read_ref_at_mem(self, gcref, ofs): return llop.raw_load(llmemory.GCREF, gcref, ofs) + # non- at specialized: must only be called with llmemory.GCREF def write_ref_at_mem(self, gcref, ofs, newvalue): llop.raw_store(lltype.Void, gcref, ofs, newvalue) # the write barrier is implied above @@ -541,6 +544,7 @@ ofs, size, sign = self.unpack_fielddescr_size(fielddescr) return self.read_int_at_mem(struct, ofs, size, sign) + @specialize.argtype(1) def bh_getfield_gc_r(self, struct, fielddescr): ofs = self.unpack_fielddescr(fielddescr) return self.read_ref_at_mem(struct, ofs) @@ -551,6 +555,7 @@ return self.read_float_at_mem(struct, ofs) bh_getfield_raw_i = bh_getfield_gc_i + bh_getfield_raw_r = bh_getfield_gc_r bh_getfield_raw_f = bh_getfield_gc_f @specialize.argtype(1) 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 @@ -175,26 +175,6 @@ repr(basesize), repr(itemsize), repr(ofs_length), p)] - def test_do_write_barrier(self): - gc_ll_descr = self.gc_ll_descr - R = lltype.GcStruct('R') - S = lltype.GcStruct('S', ('r', lltype.Ptr(R))) - s = lltype.malloc(S) - r = lltype.malloc(R) - s_hdr = gc_ll_descr.gcheaderbuilder.new_header(s) - s_gcref = lltype.cast_opaque_ptr(llmemory.GCREF, s) - r_gcref = lltype.cast_opaque_ptr(llmemory.GCREF, r) - s_adr = llmemory.cast_ptr_to_adr(s) - llmemory.cast_ptr_to_adr(r) - # - s_hdr.tid &= ~gc_ll_descr.GCClass.JIT_WB_IF_FLAG - gc_ll_descr.do_write_barrier(s_gcref, r_gcref) - assert self.llop1.record == [] # not called - # - s_hdr.tid |= gc_ll_descr.GCClass.JIT_WB_IF_FLAG - gc_ll_descr.do_write_barrier(s_gcref, r_gcref) - assert self.llop1.record == [('barrier', s_adr)] - def test_gen_write_barrier(self): gc_ll_descr = self.gc_ll_descr llop1 = self.llop1 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 @@ -264,8 +264,6 @@ def bh_setfield_raw_i(self, struct, newvalue, fielddescr): raise NotImplementedError - def bh_setfield_raw_r(self, struct, newvalue, fielddescr): - raise NotImplementedError def bh_setfield_raw_f(self, struct, newvalue, fielddescr): raise NotImplementedError 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 @@ -688,6 +688,10 @@ kind = getkind(RESULT)[0] op1 = SpaceOperation('getfield_%s_%s%s' % (argname, kind, pure), [v_inst, descr], op.result) + if op1.opname == 'getfield_raw_r': + # note: 'getfield_raw_r_pure' is used e.g. to load class + # attributes that are GC objects, so that one is supported. + raise Exception("getfield_raw_r (without _pure) not supported") # if immut in (IR_QUASIIMMUTABLE, IR_QUASIIMMUTABLE_ARRAY): descr1 = self.cpu.fielddescrof( @@ -720,6 +724,8 @@ descr = self.cpu.fielddescrof(v_inst.concretetype.TO, c_fieldname.value) kind = getkind(RESULT)[0] + if argname == 'raw' and kind == 'r': + raise Exception("setfield_raw_r not supported") return SpaceOperation('setfield_%s_%s' % (argname, kind), [v_inst, v_value, descr], None) 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 @@ -1263,14 +1263,15 @@ def bhimpl_getfield_raw_i(cpu, struct, fielddescr): return cpu.bh_getfield_raw_i(struct, fielddescr) @arguments("cpu", "i", "d", returns="r") - def bhimpl_getfield_raw_r(cpu, struct, fielddescr): + def _bhimpl_getfield_raw_r(cpu, struct, fielddescr): + # only for 'getfield_raw_r_pure' return cpu.bh_getfield_raw_r(struct, fielddescr) @arguments("cpu", "i", "d", returns="f") def bhimpl_getfield_raw_f(cpu, struct, fielddescr): return cpu.bh_getfield_raw_f(struct, fielddescr) bhimpl_getfield_raw_i_pure = bhimpl_getfield_raw_i - bhimpl_getfield_raw_r_pure = bhimpl_getfield_raw_r + bhimpl_getfield_raw_r_pure = _bhimpl_getfield_raw_r bhimpl_getfield_raw_f_pure = bhimpl_getfield_raw_f @arguments("cpu", "r", "i", "d") @@ -1290,9 +1291,6 @@ @arguments("cpu", "i", "i", "d") def bhimpl_setfield_raw_i(cpu, struct, newvalue, fielddescr): cpu.bh_setfield_raw_i(struct, newvalue, fielddescr) - @arguments("cpu", "i", "r", "d") - def bhimpl_setfield_raw_r(cpu, struct, newvalue, fielddescr): - cpu.bh_setfield_raw_r(struct, newvalue, fielddescr) @arguments("cpu", "i", "f", "d") def bhimpl_setfield_raw_f(cpu, struct, newvalue, fielddescr): cpu.bh_setfield_raw_f(struct, newvalue, fielddescr) 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 @@ -177,9 +177,8 @@ def do_setfield_raw(cpu, _, structbox, itembox, fielddescr): struct = structbox.getint() - if fielddescr.is_pointer_field(): - cpu.bh_setfield_raw_r(struct, itembox.getref_base(), fielddescr) - elif fielddescr.is_float_field(): + assert not fielddescr.is_pointer_field() + if fielddescr.is_float_field(): cpu.bh_setfield_raw_f(struct, itembox.getfloatstorage(), fielddescr) else: cpu.bh_setfield_raw_i(struct, itembox.getint(), fielddescr) 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 @@ -643,7 +643,6 @@ def _opimpl_getfield_raw_any(self, box, fielddescr): return self.execute_with_descr(rop.GETFIELD_RAW, fielddescr, box) opimpl_getfield_raw_i = _opimpl_getfield_raw_any - opimpl_getfield_raw_r = _opimpl_getfield_raw_any opimpl_getfield_raw_f = _opimpl_getfield_raw_any @arguments("box", "descr") @@ -657,7 +656,6 @@ def _opimpl_setfield_raw_any(self, box, valuebox, fielddescr): self.execute_with_descr(rop.SETFIELD_RAW, fielddescr, box, valuebox) opimpl_setfield_raw_i = _opimpl_setfield_raw_any - opimpl_setfield_raw_r = _opimpl_setfield_raw_any opimpl_setfield_raw_f = _opimpl_setfield_raw_any @arguments("box", "box", "box", "descr") diff --git a/rpython/rlib/rsre/rpy/__init__.py b/rpython/rlib/rsre/rpy/__init__.py new file mode 100644 --- /dev/null +++ b/rpython/rlib/rsre/rpy/__init__.py @@ -0,0 +1,1 @@ +from ._sre import get_code diff --git a/rpython/rlib/rsre/rpy.py b/rpython/rlib/rsre/rpy/_sre.py rename from rpython/rlib/rsre/rpy.py rename to rpython/rlib/rsre/rpy/_sre.py --- a/rpython/rlib/rsre/rpy.py +++ b/rpython/rlib/rsre/rpy/_sre.py @@ -1,46 +1,24 @@ from rpython.rlib.rsre import rsre_char -from rpython.rlib.rsre.rsre_core import match from rpython.rlib.rarithmetic import intmask -def get_hacked_sre_compile(my_compile): - """Return a copy of the sre_compile module for which the _sre - module is a custom module that has _sre.compile == my_compile - and CODESIZE == rsre_char.CODESIZE. - """ - import sre_compile, sre_constants, __builtin__, new - sre_hacked = new.module("_sre_hacked") - sre_hacked.compile = my_compile - sre_hacked.MAGIC = sre_compile.MAGIC - sre_hacked.CODESIZE = rsre_char.CODESIZE - sre_hacked.MAXREPEAT = sre_constants.MAX_REPEAT - sre_hacked.getlower = rsre_char.getlower - def my_import(name, *args): - if name == '_sre': - return sre_hacked - else: - return default_import(name, *args) - src = sre_compile.__file__ - if src.lower().endswith('.pyc') or src.lower().endswith('.pyo'): - src = src[:-1] - mod = new.module("sre_compile_hacked") - default_import = __import__ - try: - __builtin__.__import__ = my_import - execfile(src, mod.__dict__) - finally: - __builtin__.__import__ = default_import - return mod + +MAGIC = 20031017 +CODESIZE = rsre_char.CODESIZE +getlower = rsre_char.getlower + class GotIt(Exception): pass -def my_compile(pattern, flags, code, *args): + +def compile(pattern, flags, code, *args): raise GotIt([intmask(i) for i in code], flags, args) -sre_compile_hacked = get_hacked_sre_compile(my_compile) + def get_code(regexp, flags=0, allargs=False): + from . import sre_compile try: - sre_compile_hacked.compile(regexp, flags) + sre_compile.compile(regexp, flags) except GotIt, e: pass else: diff --git a/lib-python/2.7/sre_compile.py b/rpython/rlib/rsre/rpy/sre_compile.py copy from lib-python/2.7/sre_compile.py copy to rpython/rlib/rsre/rpy/sre_compile.py --- a/lib-python/2.7/sre_compile.py +++ b/rpython/rlib/rsre/rpy/sre_compile.py @@ -8,11 +8,11 @@ # See the sre.py file for information on usage and redistribution. # -"""Internal support module for sre""" +"""Internal support module for sre (copied from CPython 2.7.3)""" -import _sre, sys -import sre_parse -from sre_constants import * +import sys +from . import _sre, sre_parse +from .sre_constants import * assert _sre.MAGIC == MAGIC, "SRE module mismatch" diff --git a/lib-python/2.7/sre_constants.py b/rpython/rlib/rsre/rpy/sre_constants.py copy from lib-python/2.7/sre_constants.py copy to rpython/rlib/rsre/rpy/sre_constants.py --- a/lib-python/2.7/sre_constants.py +++ b/rpython/rlib/rsre/rpy/sre_constants.py @@ -9,7 +9,7 @@ # See the sre.py file for information on usage and redistribution. # -"""Internal support module for sre""" +"""Internal support module for sre (copied from CPython 2.7.3)""" # update when constants are added or removed @@ -20,10 +20,8 @@ MAXREPEAT = 65535 # SRE standard exception (access as sre.error) -# should this really be here? - -class error(Exception): - pass +# (use the real re.error exception class) +from re import error # operators diff --git a/lib-python/2.7/sre_parse.py b/rpython/rlib/rsre/rpy/sre_parse.py copy from lib-python/2.7/sre_parse.py copy to rpython/rlib/rsre/rpy/sre_parse.py --- a/lib-python/2.7/sre_parse.py +++ b/rpython/rlib/rsre/rpy/sre_parse.py @@ -8,19 +8,13 @@ # See the sre.py file for information on usage and redistribution. # -"""Internal support module for sre""" +"""Internal support module for sre (copied from CPython 2.7.3)""" # XXX: show string offset and offending character for all errors import sys -from sre_constants import * - -try: - from __pypy__ import newdict -except ImportError: - assert '__pypy__' not in sys.builtin_module_names - newdict = lambda _ : {} +from .sre_constants import * SPECIAL_CHARS = ".\\[{()*+?^$|" REPEAT_CHARS = "*+?{" @@ -74,7 +68,7 @@ self.flags = 0 self.open = [] self.groups = 1 - self.groupdict = newdict("module") + self.groupdict = {} def opengroup(self, name=None): gid = self.groups self.groups = gid + 1 diff --git a/rpython/rlib/rsre/rsre_re.py b/rpython/rlib/rsre/rsre_re.py --- a/rpython/rlib/rsre/rsre_re.py +++ b/rpython/rlib/rsre/rsre_re.py @@ -286,8 +286,8 @@ class Scanner: # This class is copied directly from re.py. def __init__(self, lexicon, flags=0): - from sre_constants import BRANCH, SUBPATTERN - import sre_parse + from rpython.rlib.rsre.rpy.sre_constants import BRANCH, SUBPATTERN + from rpython.rlib.rsre.rpy import sre_parse self.lexicon = lexicon # combine phrases into a compound pattern p = [] diff --git a/rpython/rlib/rsre/test/test_char.py b/rpython/rlib/rsre/test/test_char.py --- a/rpython/rlib/rsre/test/test_char.py +++ b/rpython/rlib/rsre/test/test_char.py @@ -48,7 +48,7 @@ assert not rsre_char.is_uni_word(ord(',')) def test_category(): - from sre_constants import CHCODES + from rpython.rlib.rsre.rpy.sre_constants import CHCODES cat = rsre_char.category_dispatch # assert cat(CHCODES["category_digit"], ord('1')) diff --git a/rpython/rtyper/rpbc.py b/rpython/rtyper/rpbc.py --- a/rpython/rtyper/rpbc.py +++ b/rpython/rtyper/rpbc.py @@ -596,6 +596,9 @@ def ll_str(self, none): return llstr("None") + def get_ll_eq_function(self): + return None + def get_ll_hash_function(self): return ll_none_hash diff --git a/rpython/rtyper/test/test_rdict.py b/rpython/rtyper/test/test_rdict.py --- a/rpython/rtyper/test/test_rdict.py +++ b/rpython/rtyper/test/test_rdict.py @@ -1051,6 +1051,13 @@ finally: lltype._array._check_range = original_check_range + def test_dict_with_none_key(self): + def func(i): + d = {None: i} + return d[None] + res = self.interpret(func, [42]) + assert res == 42 + class TestStress: From noreply at buildbot.pypy.org Thu Sep 12 00:25:44 2013 From: noreply at buildbot.pypy.org (pjenvey) Date: Thu, 12 Sep 2013 00:25:44 +0200 (CEST) Subject: [pypy-commit] pypy py3k: merge default Message-ID: <20130911222544.4D2E91C02DE@cobra.cs.uni-duesseldorf.de> Author: Philip Jenvey Branch: py3k Changeset: r66920:927908bea004 Date: 2013-09-11 14:17 -0700 http://bitbucket.org/pypy/pypy/changeset/927908bea004/ Log: merge default diff --git a/lib-python/2.7/argparse.py b/lib-python/2.7/argparse.py --- a/lib-python/2.7/argparse.py +++ b/lib-python/2.7/argparse.py @@ -1780,7 +1780,19 @@ # error if this argument is not allowed with other previously # seen arguments, assuming that actions that use the default # value don't really count as "present" - if argument_values is not action.default: + + # XXX PyPy bug-to-bug compatibility: "is" on primitive types + # is not consistent in CPython. We'll assume it is close + # enough for ints (which is true only for "small ints"), but + # for floats and longs and complexes we'll go for the option + # of forcing "is" to say False, like it usually does on + # CPython. A fix is pending on CPython trunk + # (http://bugs.python.org/issue18943) but that might change + # the details of the semantics and so not be applied to 2.7. + # See the line AA below. + + if (argument_values is not action.default or + type(argument_values) in (float, long, complex)): # AA seen_non_default_actions.add(action) for conflict_action in action_conflicts.get(action, []): if conflict_action in seen_non_default_actions: diff --git a/pypy/module/thread/test/test_thread.py b/pypy/module/thread/test/test_thread.py --- a/pypy/module/thread/test/test_thread.py +++ b/pypy/module/thread/test/test_thread.py @@ -187,9 +187,12 @@ skip("this OS supports too many threads to check (> 1000)") lock = _thread.allocate_lock() lock.acquire() + count = [0] def f(): + count[0] += 1 lock.acquire() lock.release() + count[0] -= 1 try: try: for i in range(1000): @@ -197,11 +200,15 @@ finally: lock.release() # wait a bit to allow most threads to finish now - self.busywait(2.0) + while count[0] > 10: + print(count[0]) # <- releases the GIL + print("ok.") except (_thread.error, MemoryError): pass else: raise Exception("could unexpectedly start 1000 threads") + # safety: check that we can start a new thread here + thread.start_new_thread(lambda: None, ()) def test_stack_size(self): import _thread diff --git a/rpython/jit/codewriter/call.py b/rpython/jit/codewriter/call.py --- a/rpython/jit/codewriter/call.py +++ b/rpython/jit/codewriter/call.py @@ -92,17 +92,6 @@ else: assert op.opname == 'indirect_call' graphs = op.args[-1].value - if graphs is None: - # special case: handle the indirect call that goes to - # the 'instantiate' methods. This check is a bit imprecise - # but it's not too bad if we mistake a random indirect call - # for the one to 'instantiate'. - from rpython.rtyper.lltypesystem import rclass - CALLTYPE = op.args[0].concretetype - if (op.opname == 'indirect_call' and len(op.args) == 2 and - CALLTYPE == rclass.OBJECT_VTABLE.instantiate): - graphs = list(self._graphs_of_all_instantiate()) - # if graphs is not None: result = [] for graph in graphs: @@ -114,11 +103,6 @@ # residual call case: we don't need to look into any graph return None - def _graphs_of_all_instantiate(self): - for vtable in self.rtyper.lltype2vtable.values(): - if vtable.instantiate: - yield vtable.instantiate._obj.graph - def guess_call_kind(self, op, is_candidate=None): if op.opname == 'direct_call': funcptr = op.args[0].value 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 @@ -166,9 +166,6 @@ 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/test/test_ajit.py b/rpython/jit/metainterp/test/test_ajit.py --- a/rpython/jit/metainterp/test/test_ajit.py +++ b/rpython/jit/metainterp/test/test_ajit.py @@ -1411,7 +1411,6 @@ self.check_resops(call=2) def test_merge_guardclass_guardvalue(self): - from rpython.rlib.objectmodel import instantiate myjitdriver = JitDriver(greens = [], reds = ['x', 'l']) class A(object): @@ -1438,7 +1437,6 @@ self.check_resops(guard_class=0, guard_value=6) def test_merge_guardnonnull_guardclass(self): - from rpython.rlib.objectmodel import instantiate myjitdriver = JitDriver(greens = [], reds = ['x', 'l']) class A(object): @@ -1468,7 +1466,6 @@ def test_merge_guardnonnull_guardvalue(self): - from rpython.rlib.objectmodel import instantiate myjitdriver = JitDriver(greens = [], reds = ['x', 'l']) class A(object): @@ -1497,7 +1494,6 @@ def test_merge_guardnonnull_guardvalue_2(self): - from rpython.rlib.objectmodel import instantiate myjitdriver = JitDriver(greens = [], reds = ['x', 'l']) class A(object): @@ -1526,7 +1522,6 @@ def test_merge_guardnonnull_guardclass_guardvalue(self): - from rpython.rlib.objectmodel import instantiate myjitdriver = JitDriver(greens = [], reds = ['x', 'l']) class A(object): diff --git a/rpython/rtyper/lltypesystem/rpbc.py b/rpython/rtyper/lltypesystem/rpbc.py --- a/rpython/rtyper/lltypesystem/rpbc.py +++ b/rpython/rtyper/lltypesystem/rpbc.py @@ -377,11 +377,20 @@ # no __init__ here, AbstractClassesPBCRepr.__init__ is good enough def _instantiate_runtime_class(self, hop, vtypeptr, r_instance): - v_instantiate = hop.genop('getfield', [vtypeptr, hop.inputconst(Void, "instantiate")], resulttype=vtypeptr.concretetype.TO.instantiate) - possible_graphs = hop.inputconst(Void, - [desc.getclassdef(None).my_instantiate_graph for desc in self.s_pbc.descriptions] - ) - v_inst = hop.genop('indirect_call', [v_instantiate, possible_graphs], resulttype=vtypeptr.concretetype.TO.instantiate.TO.RESULT) + graphs = [] + for desc in self.s_pbc.descriptions: + classdef = desc.getclassdef(None) + assert hasattr(classdef, 'my_instantiate_graph') + graphs.append(classdef.my_instantiate_graph) + c_graphs = hop.inputconst(Void, graphs) + # + # "my_instantiate = typeptr.instantiate" + c_name = hop.inputconst(Void, 'instantiate') + v_instantiate = hop.genop('getfield', [vtypeptr, c_name], + resulttype = rclass.OBJECT_VTABLE.instantiate) + # "my_instantiate()" + v_inst = hop.genop('indirect_call', [v_instantiate, c_graphs], + resulttype = rclass.OBJECTPTR) return hop.genop('cast_pointer', [v_inst], resulttype=r_instance) def getlowleveltype(self): diff --git a/rpython/rtyper/rbuiltin.py b/rpython/rtyper/rbuiltin.py --- a/rpython/rtyper/rbuiltin.py +++ b/rpython/rtyper/rbuiltin.py @@ -705,10 +705,6 @@ assert isinstance(hop.args_r[0], rclass.InstanceRepr) return hop.args_r[0].rtype_isinstance(hop) -def ll_instantiate(typeptr): # NB. used by rpbc.ClassesPBCRepr as well - my_instantiate = typeptr.instantiate - return my_instantiate() - def rtype_instantiate(hop): hop.exception_cannot_occur() s_class = hop.args_s[0] @@ -716,10 +712,9 @@ if len(s_class.descriptions) != 1: # instantiate() on a variable class vtypeptr, = hop.inputargs(rclass.get_type_repr(hop.rtyper)) - v_inst = hop.gendirectcall(ll_instantiate, vtypeptr) - return hop.genop('cast_pointer', [v_inst], # v_type implicit in r_result - resulttype = hop.r_result.lowleveltype) - + r_class = hop.args_r[0] + return r_class._instantiate_runtime_class(hop, vtypeptr, + hop.r_result.lowleveltype) classdef = s_class.any_description().getuniqueclassdef() return rclass.rtype_new_instance(hop.rtyper, classdef, hop.llops) diff --git a/rpython/translator/backendopt/gilanalysis.py b/rpython/translator/backendopt/gilanalysis.py --- a/rpython/translator/backendopt/gilanalysis.py +++ b/rpython/translator/backendopt/gilanalysis.py @@ -26,9 +26,6 @@ return False else: return False - - def analyze_instantiate_call(self, seen=None): - return False def analyze_simple_operation(self, op, graphinfo): return False diff --git a/rpython/translator/backendopt/graphanalyze.py b/rpython/translator/backendopt/graphanalyze.py --- a/rpython/translator/backendopt/graphanalyze.py +++ b/rpython/translator/backendopt/graphanalyze.py @@ -68,9 +68,6 @@ result, self.analyze_direct_call(graph, seen)) return result - def analyze_instantiate_call(self, seen=None): - return self.top_result() - def analyze_link(self, graph, link): return self.bottom_result() @@ -79,7 +76,7 @@ def compute_graph_info(self, graph): return None - def analyze(self, op, seen=None, graphinfo=None, block=None): + def analyze(self, op, seen=None, graphinfo=None): if op.opname == "direct_call": graph = get_graph(op.args[0], self.translator) if graph is None: @@ -94,18 +91,6 @@ elif op.opname == "indirect_call": graphs = op.args[-1].value if graphs is None: - if block is not None: - v_func = op.args[0] - for op1 in block.operations: - if (v_func is op1.result and - op1.opname == 'getfield' and - op1.args[0].concretetype == rclass.CLASSTYPE and - op1.args[1].value == 'instantiate'): - x = self.analyze_instantiate_call(seen) - if self.verbose and x: - self.dump_info('analyze_instantiate(%s): %r' % ( - graphs, x)) - return x if self.verbose: self.dump_info('%s to unknown' % (op,)) return self.top_result() @@ -143,7 +128,7 @@ for op in block.operations: result = self.add_to_result( result, - self.analyze(op, seen, graphinfo, block=block) + self.analyze(op, seen, graphinfo) ) if self.is_top_result(result): break @@ -177,7 +162,7 @@ graphs = self.translator.graphs for graph in graphs: for block, op in graph.iterblockops(): - self.analyze(op, block=block) + self.analyze(op) class Dependency(object): diff --git a/rpython/translator/backendopt/test/test_writeanalyze.py b/rpython/translator/backendopt/test/test_writeanalyze.py --- a/rpython/translator/backendopt/test/test_writeanalyze.py +++ b/rpython/translator/backendopt/test/test_writeanalyze.py @@ -169,8 +169,6 @@ assert not wa.analyze(op_call_m) def test_instantiate(self): - # instantiate is interesting, because it leads to one of the few cases of - # an indirect call without a list of graphs from rpython.rlib.objectmodel import instantiate class A: pass @@ -187,7 +185,7 @@ t, wa = self.translate(f, [int]) fgraph = graphof(t, f) result = wa.analyze(fgraph.startblock.operations[0]) - assert result is top_set + assert not result def test_llexternal(self): from rpython.rtyper.lltypesystem.rffi import llexternal From noreply at buildbot.pypy.org Thu Sep 12 11:07:30 2013 From: noreply at buildbot.pypy.org (arigo) Date: Thu, 12 Sep 2013 11:07:30 +0200 (CEST) Subject: [pypy-commit] pypy stmgc-c4: Baaah. jit_assembler_call() needs to say canmallocgc=True. To be on Message-ID: <20130912090730.312341C08A1@cobra.cs.uni-duesseldorf.de> Author: Armin Rigo Branch: stmgc-c4 Changeset: r66921:1bc89ff1af70 Date: 2013-09-12 11:06 +0200 http://bitbucket.org/pypy/pypy/changeset/1bc89ff1af70/ Log: Baaah. jit_assembler_call() needs to say canmallocgc=True. To be on the safe side, also say canraise=Exc. I guess that indirect_call is special-cased by various anaysis, but not jit_assembler_call. 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 @@ -507,7 +507,9 @@ 'get_write_barrier_from_array_failing_case': LLOp(sideeffects=False), 'gc_get_type_info_group': LLOp(sideeffects=False), 'll_read_timestamp': LLOp(canrun=True), - 'jit_assembler_call': LLOp(canrun=True), # similar to an 'indirect_call' + 'jit_assembler_call': LLOp(canrun=True, # similar to an 'indirect_call' + canraise=(Exception,), + canmallocgc=True), # __________ GC operations __________ From noreply at buildbot.pypy.org Thu Sep 12 11:20:32 2013 From: noreply at buildbot.pypy.org (Raemi) Date: Thu, 12 Sep 2013 11:20:32 +0200 (CEST) Subject: [pypy-commit] pypy stmgc-c4: turn inevitable before calls that don't have an effectinfo (to be safe) Message-ID: <20130912092032.8E6C41C0175@cobra.cs.uni-duesseldorf.de> Author: Remi Meier Branch: stmgc-c4 Changeset: r66922:b5034dc26351 Date: 2013-09-12 11:19 +0200 http://bitbucket.org/pypy/pypy/changeset/b5034dc26351/ Log: turn inevitable before calls that don't have an effectinfo (to be safe) 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 @@ -406,8 +406,7 @@ assert 0 llop1 = llop - if not stm or ( - self.extrainfo and self.extrainfo.call_needs_inevitable()): + if not stm or not self.extrainfo or self.extrainfo.call_needs_inevitable(): source = py.code.Source(""" def call_stub(func, args_i, args_r, args_f): fnptr = rffi.cast(lltype.Ptr(FUNC), func) diff --git a/rpython/jit/backend/llsupport/stmrewrite.py b/rpython/jit/backend/llsupport/stmrewrite.py --- a/rpython/jit/backend/llsupport/stmrewrite.py +++ b/rpython/jit/backend/llsupport/stmrewrite.py @@ -111,8 +111,8 @@ else: descr = op.getdescr() assert not descr or isinstance(descr, CallDescr) - if descr and descr.get_extra_info() and \ - descr.get_extra_info().call_needs_inevitable(): + if not descr or not descr.get_extra_info() \ + or descr.get_extra_info().call_needs_inevitable(): self.fallback_inevitable(op) else: self.newops.append(op) diff --git a/rpython/jit/backend/llsupport/test/test_stmrewrite.py b/rpython/jit/backend/llsupport/test/test_stmrewrite.py --- a/rpython/jit/backend/llsupport/test/test_stmrewrite.py +++ b/rpython/jit/backend/llsupport/test/test_stmrewrite.py @@ -469,21 +469,27 @@ def test_rewrite_getfield_gc_on_future_local_after_call(self): # XXX could detect CALLs that cannot interrupt the transaction # and/or could use the L category + class fakeextrainfo: + def call_needs_inevitable(self): + return False + T = rffi.CArrayPtr(rffi.TIME_T) + calldescr1 = get_call_descr(self.gc_ll_descr, [T], rffi.TIME_T, + fakeextrainfo()) self.check_rewrite(""" [p1] p2 = getfield_gc(p1, descr=tzdescr) - call(p2) + call(p2, descr=calldescr1) setfield_gc(p1, 5, descr=tydescr) jump(p2) """, """ [p1] cond_call_stm_b(p1, descr=P2Rdescr) p2 = getfield_gc(p1, descr=tzdescr) - call(p2) + call(p2, descr=calldescr1) cond_call_stm_b(p1, descr=P2Wdescr) setfield_gc(p1, 5, descr=tydescr) jump(p2) - """) + """, calldescr1=calldescr1) def test_getfield_raw(self): self.check_rewrite(""" @@ -658,8 +664,12 @@ """ % op) def test_call_force(self): + class fakeextrainfo: + def call_needs_inevitable(self): + return False T = rffi.CArrayPtr(rffi.TIME_T) - calldescr2 = get_call_descr(self.gc_ll_descr, [T], rffi.TIME_T) + calldescr2 = get_call_descr(self.gc_ll_descr, [T], rffi.TIME_T, + fakeextrainfo()) for op in ["call(123, descr=calldescr2)", "call_assembler(123, descr=casmdescr)", "call_may_force(123, descr=calldescr2)", From noreply at buildbot.pypy.org Thu Sep 12 16:39:46 2013 From: noreply at buildbot.pypy.org (Raemi) Date: Thu, 12 Sep 2013 16:39:46 +0200 (CEST) Subject: [pypy-commit] pypy stmgc-c4: little fix to always release a spinlock Message-ID: <20130912143946.A5B3A1C0175@cobra.cs.uni-duesseldorf.de> Author: Remi Meier Branch: stmgc-c4 Changeset: r66923:7dbb17aeb3be Date: 2013-09-12 16:39 +0200 http://bitbucket.org/pypy/pypy/changeset/7dbb17aeb3be/ Log: little fix to always release a spinlock diff --git a/rpython/translator/c/src/mem.c b/rpython/translator/c/src/mem.c --- a/rpython/translator/c/src/mem.c +++ b/rpython/translator/c/src/mem.c @@ -78,6 +78,7 @@ free(dying); return 1; } + spinlock_release(pypy_debug_alloc_lock); return 0; } From noreply at buildbot.pypy.org Thu Sep 12 16:50:43 2013 From: noreply at buildbot.pypy.org (Raemi) Date: Thu, 12 Sep 2013 16:50:43 +0200 (CEST) Subject: [pypy-commit] extradoc extradoc: draft for stm update Message-ID: <20130912145043.90EED1C0175@cobra.cs.uni-duesseldorf.de> Author: Remi Meier Branch: extradoc Changeset: r5047:be80581fecf8 Date: 2013-09-12 16:50 +0200 http://bitbucket.org/pypy/extradoc/changeset/be80581fecf8/ Log: draft for stm update diff --git a/blog/draft/stm-sept2013.rst b/blog/draft/stm-sept2013.rst new file mode 100644 --- /dev/null +++ b/blog/draft/stm-sept2013.rst @@ -0,0 +1,52 @@ +Update on STM +============= + +Hi all, + +the sprint in London was a lot of fun and very fruitful. In the last +update on STM, Armin was working on improving and specializing the +automatic barrier placement. +There is still a lot to do in that area, but that work was merged and +lowered the overhead of STM over non-STM to around **XXX**. The same +improvement has still to be done in the JIT. + +But that is not all. Right after the sprint, we were able to squeeze +the last obvious bugs in the STM-JIT combination. However, the performance +was nowhere near what we want. So until now, we fixed some of the most +obvious issues. Many come from RPython erring on the side of caution +and e.g. making a transaction inevitable even if that is not strictly +necessary, thereby limiting parallelism. +**XXX any interesting details?** +There are still many performance issues of various complexity left +to tackle. So stay tuned or contribute :) + +Now, since the JIT is all about performance, we want to at least +show you some numbers that are indicative of things to come. +Our set of STM benchmarks is very small unfortunately +(something you can help us out with), so this is +not representative of real-world performance. + +**Raytracer** from `stm-benchmarks `_: +Render times for a 1024x1024 image using 6 threads + ++-------------+----------------------+ +| Interpeter | Time (no-JIT / JIT) | ++=============+======================+ +| PyPy-2.1 | ... / ... | ++-------------+----------------------+ +| CPython | ... / - | ++-------------+----------------------+ +| PyPy-STM | ... / ... | ++-------------+----------------------+ + +**XXX same for Richards** + + +All this can be found in the `PyPy repository on the stmgc-c4 +branch `_. +Try it for yourself, but keep in mind that this is still experimental +with a lot of things yet to come. + +You can also download a prebuilt binary frome here: **XXX** + + From noreply at buildbot.pypy.org Thu Sep 12 20:36:43 2013 From: noreply at buildbot.pypy.org (mattip) Date: Thu, 12 Sep 2013 20:36:43 +0200 (CEST) Subject: [pypy-commit] pypy pypy-pyarray: test, fix __array__ method Message-ID: <20130912183643.DF4B81C135D@cobra.cs.uni-duesseldorf.de> Author: Matti Picus Branch: pypy-pyarray Changeset: r66924:87b7bca797bc Date: 2013-09-12 21:07 +0300 http://bitbucket.org/pypy/pypy/changeset/87b7bca797bc/ Log: test, fix __array__ method 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 @@ -336,7 +336,7 @@ def descr_nonzero(self, space): index_type = interp_dtype.get_dtype_cache(space).w_int64dtype return self.implementation.nonzero(space, index_type) - + def descr_tolist(self, space): if len(self.get_shape()) == 0: return self.get_scalar_value().item(space) @@ -424,6 +424,9 @@ "non-int arg not supported")) def descr___array__(self, space, w_dtype=None): + if not space.is_none(w_dtype): + raise OperationError(space.w_NotImplementedError, space.wrap( + "__array__(dtype) not implemented")) # stub implementation of __array__() return self @@ -1123,12 +1126,14 @@ if not isinstance(w_object, W_NDimArray): w___array__ = space.lookup(w_object, "__array__") if w___array__ is not None: + if space.is_none(w_dtype): + w_dtype = space.w_None w_array = space.get_and_call_function(w___array__, w_object, w_dtype) if isinstance(w_array, W_NDimArray): # feed w_array back into array() for other properties return array(space, w_array, w_dtype, False, w_order, subok, ndmin) else: - raise operationerrfmt(space.w_ValueError, + raise operationerrfmt(space.w_ValueError, "object __array__ method not producing an array") # scalars and strings w/o __array__ method @@ -1136,10 +1141,10 @@ if not issequence_w(space, w_object) or isstr: if space.is_none(w_dtype) or isstr: w_dtype = interp_ufuncs.find_dtype_for_scalar(space, w_object) - dtype = space.interp_w(interp_dtype.W_Dtype, + dtype = space.interp_w(interp_dtype.W_Dtype, space.call_function(space.gettypefor(interp_dtype.W_Dtype), w_dtype)) return W_NDimArray.new_scalar(space, dtype, w_object) - + if space.is_none(w_order): order = 'C' else: @@ -1165,7 +1170,7 @@ w_ret.implementation = w_ret.implementation.set_shape(space, w_ret, shape) return w_ret - + # not an array or incorrect dtype shape, elems_w = find_shape_and_elems(space, w_object, dtype) if dtype is None or ( diff --git a/pypy/module/micronumpy/test/test_base.py b/pypy/module/micronumpy/test/test_base.py --- a/pypy/module/micronumpy/test/test_base.py +++ b/pypy/module/micronumpy/test/test_base.py @@ -11,10 +11,13 @@ @classmethod def setup_class(cls): + isNumpy = False if option.runappdirect: if '__pypy__' not in sys.builtin_module_names: import numpy sys.modules['numpypy'] = numpy + isNumpy = True + cls.w_isNumpy = cls.space.wrap(isNumpy) cls.w_non_native_prefix = cls.space.wrap(nonnative_byteorder_prefix) cls.w_native_prefix = cls.space.wrap(byteorder_prefix) diff --git a/pypy/module/micronumpy/test/test_subtype.py b/pypy/module/micronumpy/test/test_subtype.py --- a/pypy/module/micronumpy/test/test_subtype.py +++ b/pypy/module/micronumpy/test/test_subtype.py @@ -221,3 +221,26 @@ b = a.reshape(3, 4) assert b.called_finalize == True + def test___array__(self): + from numpypy import ndarray, array, dtype + class D(ndarray): + def __new__(subtype, shape, dtype): + self = ndarray.__new__(subtype, shape, dtype) + self.id = 'subtype' + return self + class C(object): + def __init__(self, val, dtype): + self.val = val + self.dtype = dtype + def __array__(self, dtype=None): + retVal = D(self.val, dtype) + return retVal + + a = C([2, 2], int) + b = array(a) + assert b.shape == (2, 2) + if not self.isNumpy: + assert b.id == 'subtype' + assert isinstance(b, D) + c = array(a, float) + assert c.dtype is dtype(float) From noreply at buildbot.pypy.org Thu Sep 12 20:36:45 2013 From: noreply at buildbot.pypy.org (mattip) Date: Thu, 12 Sep 2013 20:36:45 +0200 (CEST) Subject: [pypy-commit] pypy pypy-pyarray: remove finished tasks from TODO Message-ID: <20130912183645.202811C135D@cobra.cs.uni-duesseldorf.de> Author: Matti Picus Branch: pypy-pyarray Changeset: r66925:13bb60bd52ac Date: 2013-09-12 21:35 +0300 http://bitbucket.org/pypy/pypy/changeset/13bb60bd52ac/ Log: remove finished tasks from TODO diff --git a/TODO.txt b/TODO.txt --- a/TODO.txt +++ b/TODO.txt @@ -4,16 +4,10 @@ - why do we need to implement array.nonzero on this branch and it was not done e.g. on default? -- interp_numarray.py :: descr___array__: the dtype method is ignored: it's - fine to have a half-working implementation, but it should raise an exception - if it's passed - TODO list by mattip =================== -- test array.nonzero() - test "from numpypy import *" esp. get_include() -- test "import numpy" emitting warning not error - test all *.h files under pypy/module/cpyext/include/numpy - make sure all cpyext changes are tested: PyBoolObject (new) @@ -29,5 +23,5 @@ all ndarrayobject.py (new) PyNumberCoerceEx() (new) PyNumberCoerce() (new) -- test require_index in create_iter, get_index in iter -- test use of __array__() and friends +- test, implement use of __array_prepare__() +- test, implement use of __array_wrap__() From noreply at buildbot.pypy.org Thu Sep 12 20:48:48 2013 From: noreply at buildbot.pypy.org (arigo) Date: Thu, 12 Sep 2013 20:48:48 +0200 (CEST) Subject: [pypy-commit] stmgc default: Print the full name of the abort reason Message-ID: <20130912184848.0A90B1C135D@cobra.cs.uni-duesseldorf.de> Author: Armin Rigo Branch: Changeset: r529:4ed9ba1552f8 Date: 2013-09-12 20:48 +0200 http://bitbucket.org/pypy/stmgc/changeset/4ed9ba1552f8/ Log: Print the full name of the abort reason diff --git a/c4/et.c b/c4/et.c --- a/c4/et.c +++ b/c4/et.c @@ -902,6 +902,7 @@ void AbortTransaction(int num) { + static const char *abort_names[] = ABORT_NAMES; struct tx_descriptor *d = thread_descriptor; unsigned long limit; struct timespec now; @@ -1003,10 +1004,10 @@ dprintf(("\n" "!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!\n" "!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!\n" - "!!!!!!!!!!!!!!!!!!!!! [%lx] abort %d\n" + "!!!!!!!!!!!!!!!!!!!!! [%lx] abort %s\n" "!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!\n" "!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!\n" - "\n", (long)d->public_descriptor_index, num)); + "\n", (long)d->public_descriptor_index, abort_names[num])); if (num != ABRT_MANUAL && d->max_aborts >= 0 && !d->max_aborts--) stm_fatalerror("unexpected abort!\n"); diff --git a/c4/et.h b/c4/et.h --- a/c4/et.h +++ b/c4/et.h @@ -124,6 +124,15 @@ #define ABRT_COLLECT_MINOR 6 #define ABRT_COLLECT_MAJOR 7 #define ABORT_REASONS 8 +#define ABORT_NAMES { "MANUAL", \ + "COMMIT", \ + "STOLEN_MODIFIED", \ + "VALIDATE_INFLIGHT", \ + "VALIDATE_COMMIT", \ + "VALIDATE_INEV", \ + "COLLECT_MINOR", \ + "COLLECT_MAJOR", \ + } #define SPLP_ABORT 0 #define SPLP_LOCKED_INFLIGHT 1 From noreply at buildbot.pypy.org Thu Sep 12 20:52:17 2013 From: noreply at buildbot.pypy.org (arigo) Date: Thu, 12 Sep 2013 20:52:17 +0200 (CEST) Subject: [pypy-commit] pypy stmgc-c4: import stmgc/4ed9ba1552f8 and hack to always print aborts Message-ID: <20130912185217.E3D7B1C1473@cobra.cs.uni-duesseldorf.de> Author: Armin Rigo Branch: stmgc-c4 Changeset: r66926:17d596a06b51 Date: 2013-09-12 20:50 +0200 http://bitbucket.org/pypy/pypy/changeset/17d596a06b51/ Log: import stmgc/4ed9ba1552f8 and hack to always print aborts diff --git a/rpython/translator/stm/src_stm/et.c b/rpython/translator/stm/src_stm/et.c --- a/rpython/translator/stm/src_stm/et.c +++ b/rpython/translator/stm/src_stm/et.c @@ -903,6 +903,7 @@ void AbortTransaction(int num) { + static const char *abort_names[] = ABORT_NAMES; struct tx_descriptor *d = thread_descriptor; unsigned long limit; struct timespec now; @@ -1001,13 +1002,15 @@ stm_invoke_callbacks_on_abort(d); stm_clear_callbacks_on_abort(d); + fprintf(stderr, "[%lx] abort %s\n", + (long)d->public_descriptor_index, abort_names[num]); dprintf(("\n" "!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!\n" "!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!\n" - "!!!!!!!!!!!!!!!!!!!!! [%lx] abort %d\n" + "!!!!!!!!!!!!!!!!!!!!! [%lx] abort %s\n" "!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!\n" "!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!\n" - "\n", (long)d->public_descriptor_index, num)); + "\n", (long)d->public_descriptor_index, abort_names[num])); if (num != ABRT_MANUAL && d->max_aborts >= 0 && !d->max_aborts--) stm_fatalerror("unexpected abort!\n"); @@ -1534,8 +1537,8 @@ (XXX statically we should know when we're outside a transaction) */ - fprintf(stderr, "[%lx] inevitable: %s\n", - (long)d->public_descriptor_index, why); + dprintf(("[%lx] inevitable: %s\n", + (long)d->public_descriptor_index, why)); cur_time = acquire_inev_mutex_and_mark_global_cur_time(d); if (d->start_time != cur_time) 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 @@ -125,6 +125,15 @@ #define ABRT_COLLECT_MINOR 6 #define ABRT_COLLECT_MAJOR 7 #define ABORT_REASONS 8 +#define ABORT_NAMES { "MANUAL", \ + "COMMIT", \ + "STOLEN_MODIFIED", \ + "VALIDATE_INFLIGHT", \ + "VALIDATE_COMMIT", \ + "VALIDATE_INEV", \ + "COLLECT_MINOR", \ + "COLLECT_MAJOR", \ + } #define SPLP_ABORT 0 #define SPLP_LOCKED_INFLIGHT 1 diff --git a/rpython/translator/stm/src_stm/revision b/rpython/translator/stm/src_stm/revision --- a/rpython/translator/stm/src_stm/revision +++ b/rpython/translator/stm/src_stm/revision @@ -1,1 +1,1 @@ -0b3f7830cb46 +4ed9ba1552f8 From noreply at buildbot.pypy.org Thu Sep 12 21:06:20 2013 From: noreply at buildbot.pypy.org (arigo) Date: Thu, 12 Sep 2013 21:06:20 +0200 (CEST) Subject: [pypy-commit] stmgc default: Add abort and inevitable fprinting to stmgc too for now Message-ID: <20130912190620.8A7741C1473@cobra.cs.uni-duesseldorf.de> Author: Armin Rigo Branch: Changeset: r530:111c09337109 Date: 2013-09-12 21:06 +0200 http://bitbucket.org/pypy/stmgc/changeset/111c09337109/ Log: Add abort and inevitable fprinting to stmgc too for now diff --git a/c4/et.c b/c4/et.c --- a/c4/et.c +++ b/c4/et.c @@ -1001,6 +1001,9 @@ stm_invoke_callbacks_on_abort(d); stm_clear_callbacks_on_abort(d); + /* XXX */ + fprintf(stderr, "[%lx] abort %s\n", + (long)d->public_descriptor_index, abort_names[num]); dprintf(("\n" "!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!\n" "!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!\n" @@ -1534,6 +1537,9 @@ (XXX statically we should know when we're outside a transaction) */ + /* XXX */ + fprintf(stderr, "[%lx] inevitable: %s\n", + (long)d->public_descriptor_index, why); dprintf(("[%lx] inevitable: %s\n", (long)d->public_descriptor_index, why)); From noreply at buildbot.pypy.org Thu Sep 12 21:07:41 2013 From: noreply at buildbot.pypy.org (arigo) Date: Thu, 12 Sep 2013 21:07:41 +0200 (CEST) Subject: [pypy-commit] pypy stmgc-c4: import stmgc/111c09337109 Message-ID: <20130912190741.0868B1C1473@cobra.cs.uni-duesseldorf.de> Author: Armin Rigo Branch: stmgc-c4 Changeset: r66927:131f1071ef10 Date: 2013-09-12 21:06 +0200 http://bitbucket.org/pypy/pypy/changeset/131f1071ef10/ Log: import stmgc/111c09337109 diff --git a/rpython/translator/stm/src_stm/et.c b/rpython/translator/stm/src_stm/et.c --- a/rpython/translator/stm/src_stm/et.c +++ b/rpython/translator/stm/src_stm/et.c @@ -1002,6 +1002,7 @@ stm_invoke_callbacks_on_abort(d); stm_clear_callbacks_on_abort(d); + /* XXX */ fprintf(stderr, "[%lx] abort %s\n", (long)d->public_descriptor_index, abort_names[num]); dprintf(("\n" @@ -1537,6 +1538,9 @@ (XXX statically we should know when we're outside a transaction) */ + /* XXX */ + fprintf(stderr, "[%lx] inevitable: %s\n", + (long)d->public_descriptor_index, why); dprintf(("[%lx] inevitable: %s\n", (long)d->public_descriptor_index, why)); diff --git a/rpython/translator/stm/src_stm/revision b/rpython/translator/stm/src_stm/revision --- a/rpython/translator/stm/src_stm/revision +++ b/rpython/translator/stm/src_stm/revision @@ -1,1 +1,1 @@ -4ed9ba1552f8 +111c09337109 From noreply at buildbot.pypy.org Thu Sep 12 22:17:05 2013 From: noreply at buildbot.pypy.org (mattip) Date: Thu, 12 Sep 2013 22:17:05 +0200 (CEST) Subject: [pypy-commit] pypy pypy-pyarray: remove non-implemented objects from TODO Message-ID: <20130912201705.5F5721C1007@cobra.cs.uni-duesseldorf.de> Author: Matti Picus Branch: pypy-pyarray Changeset: r66928:410f35e18949 Date: 2013-09-12 23:16 +0300 http://bitbucket.org/pypy/pypy/changeset/410f35e18949/ Log: remove non-implemented objects from TODO diff --git a/TODO.txt b/TODO.txt --- a/TODO.txt +++ b/TODO.txt @@ -10,14 +10,8 @@ - test "from numpypy import *" esp. get_include() - test all *.h files under pypy/module/cpyext/include/numpy - make sure all cpyext changes are tested: - PyBoolObject (new) PyComplexFromCComplex() (changed, problematic for c++?) - PyFunctionType (new) - PyMethodType (new) - PyRangeType (new) - PyTracebackType (new) _PyPackageContext (new) - Py*Flag (most new, some changed) in pythonrun.h all ndarrayobject.c copy_header_files() in api.py (changed) all ndarrayobject.py (new) From noreply at buildbot.pypy.org Fri Sep 13 08:34:27 2013 From: noreply at buildbot.pypy.org (amauryfa) Date: Fri, 13 Sep 2013 08:34:27 +0200 (CEST) Subject: [pypy-commit] pypy const-correctness: A branch to play with "const char**" in rpython code Message-ID: <20130913063427.9886B1C0175@cobra.cs.uni-duesseldorf.de> Author: Amaury Forgeot d'Arc Branch: const-correctness Changeset: r66929:ccef325ab4d3 Date: 2013-09-10 14:35 +0200 http://bitbucket.org/pypy/pypy/changeset/ccef325ab4d3/ Log: A branch to play with "const char**" in rpython code From noreply at buildbot.pypy.org Fri Sep 13 08:34:28 2013 From: noreply at buildbot.pypy.org (amauryfa) Date: Fri, 13 Sep 2013 08:34:28 +0200 (CEST) Subject: [pypy-commit] pypy const-correctness: Add a remove_const() function. Message-ID: <20130913063428.DCBC21C0E26@cobra.cs.uni-duesseldorf.de> Author: Amaury Forgeot d'Arc Branch: const-correctness Changeset: r66930:82959e78dad2 Date: 2013-09-10 15:23 +0200 http://bitbucket.org/pypy/pypy/changeset/82959e78dad2/ Log: Add a remove_const() function. No need to manually cast from "char*" to "const char**" diff --git a/rpython/rtyper/lltypesystem/lltype.py b/rpython/rtyper/lltypesystem/lltype.py --- a/rpython/rtyper/lltypesystem/lltype.py +++ b/rpython/rtyper/lltypesystem/lltype.py @@ -980,6 +980,20 @@ raise TypeError("invalid cast_opaque_ptr(): %r -> %r" % (CURTYPE, PTRTYPE)) +def remove_const(T): + "The same type as T, but with any top level const-qualifier removed." + if isinstance(T, Ptr): + return Ptr(remove_const(T.TO)) + if not T._hints.get('render_as_const'): + return T + hints = T._hints.copy() + del hints['render_as_const'] + T2 = object.__new__(type(T)) + T2.__dict__.update(T.__dict__) + T2._hints = T2._hints.copy() + del T2._hints['render_as_const'] + return T2 + def direct_fieldptr(structptr, fieldname): """Get a pointer to a field in the struct. The resulting pointer is actually of type Ptr(FixedSizeArray(FIELD, 1)). @@ -1248,7 +1262,7 @@ if len(args) != len(self._T.ARGS): raise TypeError,"calling %r with wrong argument number: %r" % (self._T, args) for i, a, ARG in zip(range(len(self._T.ARGS)), args, self._T.ARGS): - if typeOf(a) != ARG: + if typeOf(a) != remove_const(ARG): # ARG could be Void if ARG == Void: try: diff --git a/rpython/rtyper/lltypesystem/test/test_lltype.py b/rpython/rtyper/lltypesystem/test/test_lltype.py --- a/rpython/rtyper/lltypesystem/test/test_lltype.py +++ b/rpython/rtyper/lltypesystem/test/test_lltype.py @@ -210,6 +210,17 @@ assert p1b == cast_pointer(Ptr(S1bis), p3) py.test.raises(RuntimeError, "cast_pointer(Ptr(S1), p3)") +def test_remove_const(): + T = Ptr(GcArray(('v', Signed), hints={'render_as_const': True, 'y': 2})) + T2 = remove_const(T) + assert T2 != T + assert T2 == Ptr(GcArray(('v', Signed), hints={'y': 2})) + S = Ptr(Struct("s2", ('a', Signed), hints={'render_as_const': True})) + S2 = remove_const(S) + assert S2 != S + assert S2 == Ptr(Struct("s2", ('a', Signed))) + + def test_best_effort_gced_parent_detection(): py.test.skip("test not relevant any more") S2 = Struct("s2", ('a', Signed)) diff --git a/rpython/translator/c/test/test_lltyped.py b/rpython/translator/c/test/test_lltyped.py --- a/rpython/translator/c/test/test_lltyped.py +++ b/rpython/translator/c/test/test_lltyped.py @@ -954,7 +954,7 @@ s = malloc(rffi.CCHARP.TO, 2, flavor='raw') s[0] = '9' s[1] = '\0' - res = atoi(rffi.cast(rffi.CONST_CCHARP, s)) + res = atoi(s) free(s, flavor='raw') return res From noreply at buildbot.pypy.org Fri Sep 13 08:34:30 2013 From: noreply at buildbot.pypy.org (amauryfa) Date: Fri, 13 Sep 2013 08:34:30 +0200 (CEST) Subject: [pypy-commit] pypy const-correctness: Progress Message-ID: <20130913063430.162501C13E7@cobra.cs.uni-duesseldorf.de> Author: Amaury Forgeot d'Arc Branch: const-correctness Changeset: r66931:5d4e27857d0a Date: 2013-09-11 00:19 +0200 http://bitbucket.org/pypy/pypy/changeset/5d4e27857d0a/ Log: Progress diff --git a/rpython/annotator/binaryop.py b/rpython/annotator/binaryop.py --- a/rpython/annotator/binaryop.py +++ b/rpython/annotator/binaryop.py @@ -874,9 +874,7 @@ class __extend__(pairtype(SomePtr, SomePtr)): def union((p1, p2)): - assert p1.ll_ptrtype == p2.ll_ptrtype,("mixing of incompatible pointer types: %r, %r" % - (p1.ll_ptrtype, p2.ll_ptrtype)) - return SomePtr(p1.ll_ptrtype) + return SomePtr(p1.ll_ptrtype.union(p2.ll_ptrtype)) class __extend__(pairtype(SomePtr, SomeInteger)): diff --git a/rpython/rlib/rdtoa.py b/rpython/rlib/rdtoa.py --- a/rpython/rlib/rdtoa.py +++ b/rpython/rlib/rdtoa.py @@ -39,7 +39,7 @@ ) dg_strtod = rffi.llexternal( - '_PyPy_dg_strtod', [rffi.CCHARP, rffi.CCHARPP], rffi.DOUBLE, + '_PyPy_dg_strtod', [rffi.CONST_CCHARP, rffi.CCHARPP], rffi.DOUBLE, compilation_info=eci, sandboxsafe=True) dg_dtoa = rffi.llexternal( diff --git a/rpython/rtyper/llinterp.py b/rpython/rtyper/llinterp.py --- a/rpython/rtyper/llinterp.py +++ b/rpython/rtyper/llinterp.py @@ -636,7 +636,7 @@ if len(ARGS) != len(args_v): raise TypeError("graph with %d args called with wrong func ptr type: %r" %(len(args_v), ARGS)) for T, v in zip(ARGS, args_v): - if not lltype.isCompatibleType(T, v.concretetype): + if not lltype.isConvertibleFrom(T, v.concretetype): raise TypeError("graph with %r args called with wrong func ptr type: %r" % (tuple([v.concretetype for v in args_v]), ARGS)) frame = self.newsubframe(graph, args) diff --git a/rpython/rtyper/lltypesystem/lltype.py b/rpython/rtyper/lltypesystem/lltype.py --- a/rpython/rtyper/lltypesystem/lltype.py +++ b/rpython/rtyper/lltypesystem/lltype.py @@ -103,7 +103,10 @@ def __ne__(self, other): return not (self == other) - _is_compatible = __eq__ + def _is_convertible_from(self, other): + if self == other: + return True + return remove_const(self) == other def __setattr__(self, attr, nvalue): try: @@ -766,6 +769,15 @@ hints={'interior_ptr_type':True}) return R + def union(self, other): + if self == other: + return self + if remove_const(self) == remove_const(other): + return add_const(self) + raise AssertionError( + "mixing of incompatible pointer types: %r, %r" % (self, other)) + + class InteriorPtr(LowLevelType): def __init__(self, PARENTTYPE, TO, offsets): self.PARENTTYPE = PARENTTYPE @@ -984,14 +996,29 @@ "The same type as T, but with any top level const-qualifier removed." if isinstance(T, Ptr): return Ptr(remove_const(T.TO)) + if not isinstance(T, (Array, Struct)): + return T if not T._hints.get('render_as_const'): return T - hints = T._hints.copy() - del hints['render_as_const'] T2 = object.__new__(type(T)) T2.__dict__.update(T.__dict__) - T2._hints = T2._hints.copy() - del T2._hints['render_as_const'] + hints = T2._hints.copy() + del hints['render_as_const'] + T2._hints = frozendict(hints) + return T2 + +def add_const(T): + "The same type as T, but with any top level const-qualifier removed." + if isinstance(T, Ptr): + return Ptr(add_const(T.TO)) + assert isinstance(T, (Array, Struct)) + if T._hints.get('render_as_const'): + return T + T2 = object.__new__(type(T)) + T2.__dict__.update(T.__dict__) + hints = T2._hints.copy() + hints['render_as_const'] = True + T2._hints = frozendict(hints) return T2 def direct_fieldptr(structptr, fieldname): @@ -1212,7 +1239,7 @@ if isinstance(T1, ContainerType): raise TypeError("cannot directly assign to container array items") T2 = typeOf(val) - if T2 != T1: + if not isConvertibleFrom(T1, T2): from rpython.rtyper.lltypesystem import rffi if T1 is rffi.VOIDP and isinstance(T2, Ptr): # Any pointer is convertible to void* @@ -1262,7 +1289,7 @@ if len(args) != len(self._T.ARGS): raise TypeError,"calling %r with wrong argument number: %r" % (self._T, args) for i, a, ARG in zip(range(len(self._T.ARGS)), args, self._T.ARGS): - if typeOf(a) != remove_const(ARG): + if not isConvertibleFrom(ARG, typeOf(a)): # ARG could be Void if ARG == Void: try: @@ -2134,8 +2161,8 @@ raise ValueError("init_identity_hash(): not for varsized types") p._obj._hash_cache_ = intmask(value) -def isCompatibleType(TYPE1, TYPE2): - return TYPE1._is_compatible(TYPE2) +def isConvertibleFrom(TYPE1, TYPE2): + return TYPE1._is_convertible_from(TYPE2) def enforce(TYPE, value): return TYPE._enforce(value) diff --git a/rpython/rtyper/lltypesystem/rffi.py b/rpython/rtyper/lltypesystem/rffi.py --- a/rpython/rtyper/lltypesystem/rffi.py +++ b/rpython/rtyper/lltypesystem/rffi.py @@ -650,12 +650,14 @@ CCHARP = lltype.Ptr(lltype.Array(lltype.Char, hints={'nolength': True})) # const char * -CONST_CCHARP = lltype.Ptr(lltype.Array(lltype.Char, hints={'nolength': True, - 'render_as_const': True})) +CONST_CCHARP = lltype.add_const(CCHARP) # wchar_t * CWCHARP = lltype.Ptr(lltype.Array(lltype.UniChar, hints={'nolength': True})) +# const wchar_t * +CONST_CWCHARP = lltype.add_const(CWCHARP) + # int *, unsigned int *, etc. #INTP = ... see setup() above @@ -684,6 +686,7 @@ from rpython.rtyper.annlowlevel import llstr as llstrtype from rpython.rtyper.annlowlevel import hlstr as hlstrtype TYPEP = CCHARP + CONST_TYPEP = CONST_CCHARP ll_char_type = lltype.Char lastchar = '\x00' builder_class = StringBuilder @@ -694,6 +697,7 @@ from rpython.rtyper.annlowlevel import llunicode as llstrtype from rpython.rtyper.annlowlevel import hlunicode as hlstrtype TYPEP = CWCHARP + CONST_TYPEP = CONST_CWCHARP ll_char_type = lltype.UniChar lastchar = u'\x00' builder_class = UnicodeBuilder @@ -710,7 +714,7 @@ ll_s = llstrtype(s) copy_string_to_raw(ll_s, array, 0, i) array[i] = lastchar - return array + return cast(CONST_TYPEP, array) str2charp._annenforceargs_ = [strtype, bool] def free_charp(cp, track_allocation=True): @@ -867,6 +871,7 @@ # char** CCHARPP = lltype.Ptr(lltype.Array(CCHARP, hints={'nolength': True})) +CONST_CCHARPP = lltype.Ptr(lltype.Array(CONST_CCHARP, hints={'nolength': True})) def liststr2charpp(l): """ list[str] -> char**, NULL terminated diff --git a/rpython/rtyper/lltypesystem/test/test_rffi.py b/rpython/rtyper/lltypesystem/test/test_rffi.py --- a/rpython/rtyper/lltypesystem/test/test_rffi.py +++ b/rpython/rtyper/lltypesystem/test/test_rffi.py @@ -57,7 +57,7 @@ def test_string(self): eci = ExternalCompilationInfo(includes=['string.h']) - z = llexternal('strlen', [CCHARP], Signed, compilation_info=eci) + z = llexternal('strlen', [CONST_CCHARP], Signed, compilation_info=eci) def f(): s = str2charp("xxx") @@ -70,7 +70,7 @@ def test_unicode(self): eci = ExternalCompilationInfo(includes=['string.h']) - z = llexternal('wcslen', [CWCHARP], Signed, compilation_info=eci) + z = llexternal('wcslen', [CONST_CWCHARP], Signed, compilation_info=eci) def f(): s = unicode2wcharp(u"xxx\xe9") @@ -87,7 +87,7 @@ #include #include - char *f(char* arg) + char *f(const char* arg) { char *ret; /* lltype.free uses OP_RAW_FREE, we must allocate @@ -99,8 +99,8 @@ } """) eci = ExternalCompilationInfo(separate_module_sources=[c_source], - post_include_bits=['char *f(char*);']) - z = llexternal('f', [CCHARP], CCHARP, compilation_info=eci) + post_include_bits=['char *f(const char*);']) + z = llexternal('f', [CONST_CCHARP], CCHARP, compilation_info=eci) def f(): s = str2charp("xxx") @@ -117,7 +117,7 @@ c_source = """ #include - int f(char *args[]) { + int f(const char *args[]) { char **p = args; int l = 0; while (*p) { @@ -128,11 +128,11 @@ } """ eci = ExternalCompilationInfo(separate_module_sources=[c_source]) - z = llexternal('f', [CCHARPP], Signed, compilation_info=eci) + z = llexternal('f', [CONST_CCHARPP], Signed, compilation_info=eci) def f(): l = ["xxx", "x", "xxxx"] - ss = liststr2charpp(l) + ss = liststr2charpp(cast(CONST_CCHARPP, l)) result = z(ss) free_charpp(ss) return result @@ -617,14 +617,14 @@ def test_stringpolicy1(self): eci = ExternalCompilationInfo(includes=['string.h']) - strlen = llexternal('strlen', [CCHARP], SIZE_T, compilation_info=eci) + strlen = llexternal('strlen', [CONST_CCHARP], SIZE_T, compilation_info=eci) def f(): return cast(SIGNED, strlen("Xxx")) assert interpret(f, [], backendopt=True) == 3 def test_stringpolicy3(self): eci = ExternalCompilationInfo(includes=['string.h']) - strlen = llexternal('strlen', [CCHARP], INT, compilation_info=eci) + strlen = llexternal('strlen', [CONST_CCHARP], INT, compilation_info=eci) def f(): ll_str = str2charp("Xxx") res = strlen(ll_str) @@ -635,7 +635,7 @@ def test_stringpolicy_mixed(self): eci = ExternalCompilationInfo(includes=['string.h']) - strlen = llexternal('strlen', [CCHARP], SIZE_T, + strlen = llexternal('strlen', [CONST_CCHARP], SIZE_T, compilation_info=eci) def f(): res1 = strlen("abcd") diff --git a/rpython/rtyper/module/ll_os_environ.py b/rpython/rtyper/module/ll_os_environ.py --- a/rpython/rtyper/module/ll_os_environ.py +++ b/rpython/rtyper/module/ll_os_environ.py @@ -115,13 +115,13 @@ def r_putenv(name, value): just_a_placeholder -os_getenv = rffi.llexternal('getenv', [rffi.CCHARP], rffi.CCHARP, +os_getenv = rffi.llexternal('getenv', [rffi.CONST_CCHARP], rffi.CCHARP, threadsafe=False) -os_putenv = rffi.llexternal('putenv', [rffi.CCHARP], rffi.INT) +os_putenv = rffi.llexternal('putenv', [rffi.CONST_CCHARP], rffi.INT) if _WIN32: - _wgetenv = rffi.llexternal('_wgetenv', [rffi.CWCHARP], rffi.CWCHARP, + _wgetenv = rffi.llexternal('_wgetenv', [rffi.CONST_CWCHARP], rffi.CWCHARP, compilation_info=eci, threadsafe=False) - _wputenv = rffi.llexternal('_wputenv', [rffi.CWCHARP], rffi.INT, + _wputenv = rffi.llexternal('_wputenv', [rffi.CONST_CWCHARP], rffi.INT, compilation_info=eci) class EnvKeepalive: diff --git a/rpython/rtyper/rmodel.py b/rpython/rtyper/rmodel.py --- a/rpython/rtyper/rmodel.py +++ b/rpython/rtyper/rmodel.py @@ -3,7 +3,7 @@ from rpython.rtyper.error import TyperError, MissingRTypeOperation from rpython.rtyper.lltypesystem import lltype from rpython.rtyper.lltypesystem.lltype import (Void, Bool, Float, typeOf, - LowLevelType, isCompatibleType) + LowLevelType, isConvertibleFrom) from rpython.tool.pairtype import pairtype, extendabletype, pair @@ -125,7 +125,7 @@ realtype = typeOf(value) except (AssertionError, AttributeError, TypeError): realtype = '???' - if realtype != self.lowleveltype: + if realtype != lltype.remove_const(self.lowleveltype): raise TyperError("convert_const(self = %r, value = %r)" % ( self, value)) return value @@ -400,7 +400,7 @@ realtype = typeOf(value) except (AssertionError, AttributeError): realtype = '???' - if not isCompatibleType(realtype, lltype): + if not isConvertibleFrom(lltype, realtype): raise TyperError("inputconst(reqtype = %s, value = %s):\n" "expected a %r,\n" " got a %r" % (reqtype, value, diff --git a/rpython/translator/c/support.py b/rpython/translator/c/support.py --- a/rpython/translator/c/support.py +++ b/rpython/translator/c/support.py @@ -66,7 +66,7 @@ # check. Something else will blow up instead, probably # very confusingly. if not is_pointer_to_forward_ref(ACTUAL_TYPE): - assert ACTUAL_TYPE == T + assert lltype.isConvertibleFrom(T, ACTUAL_TYPE) return c.value From noreply at buildbot.pypy.org Fri Sep 13 08:34:31 2013 From: noreply at buildbot.pypy.org (amauryfa) Date: Fri, 13 Sep 2013 08:34:31 +0200 (CEST) Subject: [pypy-commit] pypy const-correctness: Progress Message-ID: <20130913063431.3A0F51C13EE@cobra.cs.uni-duesseldorf.de> Author: Amaury Forgeot d'Arc Branch: const-correctness Changeset: r66932:d88269fee931 Date: 2013-09-11 00:58 +0200 http://bitbucket.org/pypy/pypy/changeset/d88269fee931/ Log: Progress diff --git a/rpython/rtyper/lltypesystem/rffi.py b/rpython/rtyper/lltypesystem/rffi.py --- a/rpython/rtyper/lltypesystem/rffi.py +++ b/rpython/rtyper/lltypesystem/rffi.py @@ -190,18 +190,20 @@ for i, TARGET in unrolling_arg_tps: arg = args[i] freeme = None - if TARGET == CCHARP: + if TARGET == CCHARP and isinstance(arg, str): + raise AssertionError("Strings should be converted to CONST_CCHARP") + if TARGET == CONST_CCHARP: if arg is None: - arg = lltype.nullptr(CCHARP.TO) # None => (char*)NULL + arg = lltype.nullptr(CONST_CCHARP.TO) # None => (const char*)NULL freeme = arg elif isinstance(arg, str): arg = str2charp(arg) # XXX leaks if a str2charp() fails with MemoryError # and was not the first in this function freeme = arg - elif TARGET == CWCHARP: + elif TARGET == CONST_CWCHARP: if arg is None: - arg = lltype.nullptr(CWCHARP.TO) # None => (wchar_t*)NULL + arg = lltype.nullptr(CONST_CWCHARP.TO) # None => (wchar_t*)NULL freeme = arg elif isinstance(arg, unicode): arg = unicode2wcharp(arg) @@ -876,10 +878,10 @@ def liststr2charpp(l): """ list[str] -> char**, NULL terminated """ - array = lltype.malloc(CCHARPP.TO, len(l) + 1, flavor='raw') + array = lltype.malloc(CONST_CCHARPP.TO, len(l) + 1, flavor='raw') for i in range(len(l)): array[i] = str2charp(l[i]) - array[len(l)] = lltype.nullptr(CCHARP.TO) + array[len(l)] = lltype.nullptr(CONST_CCHARP.TO) return array liststr2charpp._annenforceargs_ = [[annmodel.s_Str0]] # List of strings # Make a copy for the ll_os.py module 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 @@ -255,10 +255,10 @@ @registering_if(os, 'execv') def register_os_execv(self): eci = self.gcc_profiling_bug_workaround( - 'int _noprof_execv(char *path, char *argv[])', + 'int _noprof_execv(const char *path, char *argv[])', 'return execv(path, argv);') os_execv = self.llexternal('_noprof_execv', - [rffi.CCHARP, rffi.CCHARPP], + [rffi.CONST_CCHARP, rffi.CCHARPP], rffi.INT, compilation_info = eci) def execv_llimpl(path, args): @@ -274,10 +274,10 @@ @registering_if(os, 'execve') def register_os_execve(self): eci = self.gcc_profiling_bug_workaround( - 'int _noprof_execve(char *filename, char *argv[], char *envp[])', + 'int _noprof_execve(const char *filename, const char *argv[], const char *envp[])', 'return execve(filename, argv, envp);') os_execve = self.llexternal( - '_noprof_execve', [rffi.CCHARP, rffi.CCHARPP, rffi.CCHARPP], + '_noprof_execve', [rffi.CONST_CCHARP, rffi.CONST_CCHARPP, rffi.CONST_CCHARPP], rffi.INT, compilation_info = eci) def execve_llimpl(path, args, env): @@ -579,7 +579,7 @@ @registering_if(os, 'chroot') def register_os_chroot(self): - os_chroot = self.llexternal('chroot', [rffi.CCHARP], rffi.INT) + os_chroot = self.llexternal('chroot', [rffi.CONST_CCHARP], rffi.INT) def chroot_llimpl(arg): result = os_chroot(arg) if result == -1: @@ -778,7 +778,7 @@ @registering_str_unicode(os.open) def register_os_open(self, traits): os_open = self.llexternal(traits.posix_function_name('open'), - [traits.CCHARP, rffi.INT, rffi.MODE_T], + [traits.CONST_CCHARP, rffi.INT, rffi.MODE_T], rffi.INT) def os_open_llimpl(path, flags, mode): result = rffi.cast(lltype.Signed, os_open(path, flags, mode)) @@ -998,7 +998,7 @@ @registering_str_unicode(os.access) def register_os_access(self, traits): os_access = self.llexternal(traits.posix_function_name('access'), - [traits.CCHARP, rffi.INT], + [traits.CONST_CCHARP, rffi.INT], rffi.INT) if sys.platform.startswith('win'): @@ -1193,7 +1193,7 @@ @registering_if(os, 'chown') def register_os_chown(self): - os_chown = self.llexternal('chown', [rffi.CCHARP, rffi.INT, rffi.INT], + os_chown = self.llexternal('chown', [rffi.CONST_CCHARP, rffi.INT, rffi.INT], rffi.INT) def os_chown_llimpl(path, uid, gid): @@ -1336,7 +1336,7 @@ @registering(os.system) def register_os_system(self): - os_system = self.llexternal('system', [rffi.CCHARP], rffi.INT) + os_system = self.llexternal('system', [rffi.CONST_CCHARP], rffi.INT) def system_llimpl(command): res = os_system(command) @@ -1370,7 +1370,7 @@ @registering_str_unicode(os.chdir) def register_os_chdir(self, traits): os_chdir = self.llexternal(traits.posix_function_name('chdir'), - [traits.CCHARP], rffi.INT) + [traits.CONST_CCHARP], rffi.INT) def os_chdir_llimpl(path): res = rffi.cast(lltype.Signed, os_chdir(path)) @@ -1388,7 +1388,7 @@ @registering_str_unicode(os.mkdir) def register_os_mkdir(self, traits): os_mkdir = self.llexternal(traits.posix_function_name('mkdir'), - [traits.CCHARP, rffi.MODE_T], rffi.INT) + [traits.CONST_CCHARP, rffi.MODE_T], rffi.INT) if sys.platform == 'win32': from rpython.rtyper.module.ll_win32file import make_win32_traits diff --git a/rpython/rtyper/module/ll_os_environ.py b/rpython/rtyper/module/ll_os_environ.py --- a/rpython/rtyper/module/ll_os_environ.py +++ b/rpython/rtyper/module/ll_os_environ.py @@ -196,7 +196,7 @@ r_putenv(name, '') if hasattr(__import__(os.name), 'unsetenv'): - os_unsetenv = rffi.llexternal('unsetenv', [rffi.CCHARP], rffi.INT) + os_unsetenv = rffi.llexternal('unsetenv', [rffi.CONST_CCHARP], rffi.INT) def unsetenv_llimpl(name): with rffi.scoped_str2charp(name) as l_name: diff --git a/rpython/rtyper/module/ll_os_stat.py b/rpython/rtyper/module/ll_os_stat.py --- a/rpython/rtyper/module/ll_os_stat.py +++ b/rpython/rtyper/module/ll_os_stat.py @@ -320,7 +320,7 @@ if name != 'fstat': arg_is_path = True s_arg = traits.str0 - ARG1 = traits.CCHARP + ARG1 = traits.CONST_CCHARP else: arg_is_path = False s_arg = int @@ -389,7 +389,7 @@ if name != 'fstatvfs': arg_is_path = True s_arg = traits.str0 - ARG1 = traits.CCHARP + ARG1 = traits.CONST_CCHARP else: arg_is_path = False s_arg = int diff --git a/rpython/rtyper/module/support.py b/rpython/rtyper/module/support.py --- a/rpython/rtyper/module/support.py +++ b/rpython/rtyper/module/support.py @@ -48,6 +48,7 @@ str0 = annmodel.s_Str0 CHAR = rffi.CHAR CCHARP = rffi.CCHARP + CONST_CCHARP = rffi.CONST_CCHARP charp2str = staticmethod(rffi.charp2str) scoped_str2charp = staticmethod(rffi.scoped_str2charp) str2charp = staticmethod(rffi.str2charp) @@ -67,6 +68,7 @@ str0 = annmodel.s_Unicode0 CHAR = rffi.WCHAR_T CCHARP = rffi.CWCHARP + CONST_CCHARP = rffi.CONST_CWCHARP charp2str = staticmethod(rffi.wcharp2unicode) str2charp = staticmethod(rffi.unicode2wcharp) scoped_str2charp = staticmethod(rffi.scoped_unicode2wcharp) From noreply at buildbot.pypy.org Fri Sep 13 08:34:34 2013 From: noreply at buildbot.pypy.org (amauryfa) Date: Fri, 13 Sep 2013 08:34:34 +0200 (CEST) Subject: [pypy-commit] pypy const-correctness: More fixes, seems to translate Message-ID: <20130913063434.BBA631C146E@cobra.cs.uni-duesseldorf.de> Author: Amaury Forgeot d'Arc Branch: const-correctness Changeset: r66935:66c9a93ea930 Date: 2013-09-13 00:09 +0200 http://bitbucket.org/pypy/pypy/changeset/66c9a93ea930/ Log: More fixes, seems to translate 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 @@ -930,6 +930,7 @@ def descr_setstate(self, space, w_state): from rpython.rtyper.lltypesystem import rffi + from rpython.rlib.rawstorage import RAW_STORAGE_PTR shape = space.getitem(w_state, space.wrap(1)) dtype = space.getitem(w_state, space.wrap(2)) @@ -937,9 +938,11 @@ isfortran = space.getitem(w_state, space.wrap(3)) storage = space.getitem(w_state, space.wrap(4)) + raw_storage = rffi.str2charp(space.str_w(storage), track_allocation=False) + raw_storage = rffi.cast(RAW_STORAGE_PTR, raw_storage) self.implementation = W_NDimArray.from_shape_and_storage(space, [space.int_w(i) for i in space.listview(shape)], - rffi.str2charp(space.str_w(storage), track_allocation=False), + raw_storage, dtype, owning=True).implementation def descr___array_finalize__(self, space, w_obj): diff --git a/rpython/rtyper/lltypesystem/lltype.py b/rpython/rtyper/lltypesystem/lltype.py --- a/rpython/rtyper/lltypesystem/lltype.py +++ b/rpython/rtyper/lltypesystem/lltype.py @@ -104,6 +104,8 @@ return not (self == other) def _is_convertible_from(self, other): + # Sometimes this function is called with something completely + # different, for example the string "??". if self == other: return True return remove_const(self) == other diff --git a/rpython/rtyper/rmodel.py b/rpython/rtyper/rmodel.py --- a/rpython/rtyper/rmodel.py +++ b/rpython/rtyper/rmodel.py @@ -125,7 +125,7 @@ realtype = typeOf(value) except (AssertionError, AttributeError, TypeError): realtype = '???' - if realtype != lltype.remove_const(self.lowleveltype): + if not lltype.isConvertibleFrom(self.lowleveltype, realtype): raise TyperError("convert_const(self = %r, value = %r)" % ( self, value)) return value diff --git a/rpython/rtyper/rptr.py b/rpython/rtyper/rptr.py --- a/rpython/rtyper/rptr.py +++ b/rpython/rtyper/rptr.py @@ -112,7 +112,7 @@ class __extend__(pairtype(PtrRepr, PtrRepr)): def convert_from_to((r_ptr1, r_ptr2), v, llop): - assert r_ptr1.lowleveltype == r_ptr2.lowleveltype + assert lltype.isConvertibleFrom(r_ptr2.lowleveltype, r_ptr1.lowleveltype) return v diff --git a/rpython/rtyper/rtyper.py b/rpython/rtyper/rtyper.py --- a/rpython/rtyper/rtyper.py +++ b/rpython/rtyper/rtyper.py @@ -23,7 +23,7 @@ from rpython.rtyper.exceptiondata import ExceptionData from rpython.rtyper.lltypesystem.lltype import (Signed, Void, LowLevelType, Ptr, ContainerType, FuncType, functionptr, typeOf, RuntimeTypeInfo, - attachRuntimeTypeInfo, Primitive) + attachRuntimeTypeInfo, Primitive, isConvertibleFrom) from rpython.rtyper.rmodel import Repr, inputconst, BrokenReprTyperError from rpython.rtyper.typesystem import LowLevelTypeSystem from rpython.rtyper.normalizecalls import perform_normalizations @@ -861,7 +861,7 @@ if v is NotImplemented: raise TyperError("don't know how to convert from %r to %r" % (r_from, r_to)) - if v.concretetype != r_to.lowleveltype: + if not isConvertibleFrom(r_to.lowleveltype, v.concretetype): raise TyperError("bug in conversion from %r to %r: " "returned a %r" % (r_from, r_to, v.concretetype)) diff --git a/rpython/rtyper/tool/rffi_platform.py b/rpython/rtyper/tool/rffi_platform.py --- a/rpython/rtyper/tool/rffi_platform.py +++ b/rpython/rtyper/tool/rffi_platform.py @@ -489,7 +489,7 @@ def prepare_code(self): yield '#ifdef %s' % self.macro yield 'int i;' - yield 'char *p = %s;' % self.name + yield 'const char *p = %s;' % self.name yield 'dump("defined", 1);' yield 'for (i = 0; p[i] != 0; i++ ) {' yield ' printf("value_%d: %d\\n", i, (int)(unsigned char)p[i]);' From noreply at buildbot.pypy.org Fri Sep 13 08:34:33 2013 From: noreply at buildbot.pypy.org (amauryfa) Date: Fri, 13 Sep 2013 08:34:33 +0200 (CEST) Subject: [pypy-commit] pypy const-correctness: progress Message-ID: <20130913063433.9C59F1C1469@cobra.cs.uni-duesseldorf.de> Author: Amaury Forgeot d'Arc Branch: const-correctness Changeset: r66934:3bd6335582cd Date: 2013-09-11 23:21 +0200 http://bitbucket.org/pypy/pypy/changeset/3bd6335582cd/ Log: progress 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 @@ -328,7 +328,7 @@ # ____________________________________________________________ -rffi_fdopen = rffi.llexternal("fdopen", [rffi.INT, rffi.CCHARP], rffi.CCHARP) +rffi_fdopen = rffi.llexternal("fdopen", [rffi.INT, rffi.CONST_CCHARP], rffi.CCHARP) rffi_setbuf = rffi.llexternal("setbuf", [rffi.CCHARP, rffi.CCHARP], lltype.Void) rffi_fclose = rffi.llexternal("fclose", [rffi.CCHARP], rffi.INT) 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 @@ -105,7 +105,7 @@ # ____________________________________________________________ sprintf_longdouble = rffi.llexternal( - "sprintf", [rffi.CCHARP, rffi.CCHARP, rffi.LONGDOUBLE], lltype.Void, + "sprintf", [rffi.CCHARP, rffi.CONST_CCHARP, rffi.LONGDOUBLE], lltype.Void, _nowrapper=True, sandboxsafe=True) FORMAT_LONGDOUBLE = rffi.str2charp("%LE") 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 @@ -115,8 +115,8 @@ return w_result -_strcoll = rlocale.external('strcoll', [rffi.CCHARP, rffi.CCHARP], rffi.INT) -_wcscoll = rlocale.external('wcscoll', [rffi.CWCHARP, rffi.CWCHARP], rffi.INT) +_strcoll = rlocale.external('strcoll', [rffi.CONST_CCHARP, rffi.CONST_CCHARP], rffi.INT) +_wcscoll = rlocale.external('wcscoll', [rffi.CONST_CWCHARP, rffi.CONST_CWCHARP], rffi.INT) def strcoll(space, w_s1, w_s2): @@ -147,7 +147,7 @@ return space.wrap(result) _strxfrm = rlocale.external('strxfrm', - [rffi.CCHARP, rffi.CCHARP, rffi.SIZE_T], rffi.SIZE_T) + [rffi.CCHARP, rffi.CONST_CCHARP, rffi.SIZE_T], rffi.SIZE_T) @unwrap_spec(s=str) def strxfrm(space, s): @@ -193,7 +193,7 @@ # HAVE_LIBINTL dependence if rlocale.HAVE_LIBINTL: - _gettext = rlocale.external('gettext', [rffi.CCHARP], rffi.CCHARP) + _gettext = rlocale.external('gettext', [rffi.CONST_CCHARP], rffi.CCHARP) @unwrap_spec(msg=str) def gettext(space, msg): @@ -205,7 +205,7 @@ finally: rffi.free_charp(msg_c) - _dgettext = rlocale.external('dgettext', [rffi.CCHARP, rffi.CCHARP], rffi.CCHARP) + _dgettext = rlocale.external('dgettext', [rffi.CONST_CCHARP, rffi.CONST_CCHARP], rffi.CCHARP) @unwrap_spec(msg=str) def dgettext(space, w_domain, msg): @@ -238,7 +238,7 @@ return space.wrap(result) - _dcgettext = rlocale.external('dcgettext', [rffi.CCHARP, rffi.CCHARP, rffi.INT], + _dcgettext = rlocale.external('dcgettext', [rffi.CONST_CCHARP, rffi.CONST_CCHARP, rffi.INT], rffi.CCHARP) @unwrap_spec(msg=str, category=int) @@ -275,7 +275,7 @@ return space.wrap(result) - _textdomain = rlocale.external('textdomain', [rffi.CCHARP], rffi.CCHARP) + _textdomain = rlocale.external('textdomain', [rffi.CONST_CCHARP], rffi.CCHARP) def textdomain(space, w_domain): """textdomain(domain) -> string @@ -299,7 +299,7 @@ return space.wrap(result) - _bindtextdomain = rlocale.external('bindtextdomain', [rffi.CCHARP, rffi.CCHARP], + _bindtextdomain = rlocale.external('bindtextdomain', [rffi.CONST_CCHARP, rffi.CONST_CCHARP], rffi.CCHARP) @unwrap_spec(domain=str) @@ -330,7 +330,7 @@ return space.wrap(rffi.charp2str(dirname)) _bind_textdomain_codeset = rlocale.external('bind_textdomain_codeset', - [rffi.CCHARP, rffi.CCHARP], rffi.CCHARP) + [rffi.CONST_CCHARP, rffi.CONST_CCHARP], rffi.CCHARP) if rlocale.HAVE_BIND_TEXTDOMAIN_CODESET: @unwrap_spec(domain=str) diff --git a/pypy/module/cppyy/capi/loadable_capi.py b/pypy/module/cppyy/capi/loadable_capi.py --- a/pypy/module/cppyy/capi/loadable_capi.py +++ b/pypy/module/cppyy/capi/loadable_capi.py @@ -64,7 +64,7 @@ else: # only other use is sring n = len(obj._string) assert raw_string == rffi.cast(rffi.CCHARP, 0) - raw_string = rffi.str2charp(obj._string) + raw_string = rffi.cast(rffi.CCHARP, rffi.str2charp(obj._string)) data = rffi.cast(rffi.CCHARPP, data) data[0] = raw_string 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 @@ -153,5 +153,5 @@ w_str = space.wrap(s) w_base = space.wrap(rffi.cast(lltype.Signed, base)) if pend: - pend[0] = rffi.ptradd(str, len(s)) + pend[0] = rffi.cast(rffi.CCHARP, rffi.ptradd(str, len(s))) return space.call_function(space.w_int, w_str, w_base) 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 @@ -183,7 +183,7 @@ w_str = space.wrap(s) w_base = space.wrap(rffi.cast(lltype.Signed, base)) if pend: - pend[0] = rffi.ptradd(str, len(s)) + pend[0] = rffi.cast(rffi.CCHARP, rffi.ptradd(str, len(s))) return space.call_function(space.w_long, w_str, w_base) @cpython_api([rffi.VOIDP], PyObject) 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 @@ -74,7 +74,7 @@ func_target = rffi.cast(getattrfunc, func) check_num_args(space, w_args, 1) args_w = space.fixedview(w_args) - name_ptr = rffi.str2charp(space.str_w(args_w[0])) + name_ptr = rffi.cast(rffi.CCHARP, rffi.str2charp(space.str_w(args_w[0]))) try: return generic_cpy_call(space, func_target, w_self, name_ptr) finally: 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 @@ -208,7 +208,8 @@ # Copy unicode buffer w_unicode = from_ref(space, ref) u = space.unicode_w(w_unicode) - ref_unicode.c_buffer = rffi.unicode2wcharp(u) + # remove 'const' modifier + ref_unicode.c_buffer = rffi.cast(rffi.CWCHARP, rffi.unicode2wcharp(u)) return ref_unicode.c_buffer @cpython_api([PyObject], rffi.CWCHARP) diff --git a/pypy/module/fcntl/interp_fcntl.py b/pypy/module/fcntl/interp_fcntl.py --- a/pypy/module/fcntl/interp_fcntl.py +++ b/pypy/module/fcntl/interp_fcntl.py @@ -109,7 +109,7 @@ if not e.match(space, space.w_TypeError): raise else: - ll_arg = rffi.str2charp(arg) + ll_arg = rffi.cast(rffi.CCHARP, rffi.str2charp(arg)) rv = fcntl_str(fd, op, ll_arg) arg = rffi.charpsize2str(ll_arg, len(arg)) lltype.free(ll_arg, flavor='raw') @@ -217,7 +217,7 @@ raise else: arg = rwbuffer.as_str() - ll_arg = rffi.str2charp(arg) + ll_arg = rffi.cast(rffi.CCHARP, rffi.str2charp(arg)) rv = ioctl_str(fd, op, ll_arg) arg = rffi.charpsize2str(ll_arg, len(arg)) lltype.free(ll_arg, flavor='raw') @@ -244,7 +244,7 @@ if not e.match(space, space.w_TypeError): raise else: - ll_arg = rffi.str2charp(arg) + ll_arg = rffi.cast(rffi.CCHARP, rffi.str2charp(arg)) rv = ioctl_str(fd, op, ll_arg) arg = rffi.charpsize2str(ll_arg, len(arg)) lltype.free(ll_arg, flavor='raw') 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 @@ -352,9 +352,9 @@ # Declarations of external functions XML_ParserCreate = expat_external( - 'XML_ParserCreate', [rffi.CCHARP], XML_Parser) + 'XML_ParserCreate', [rffi.CONST_CCHARP], XML_Parser) XML_ParserCreateNS = expat_external( - 'XML_ParserCreateNS', [rffi.CCHARP, rffi.CHAR], XML_Parser) + 'XML_ParserCreateNS', [rffi.CONST_CCHARP, rffi.CHAR], XML_Parser) XML_ParserFree = expat_external( 'XML_ParserFree', [XML_Parser], lltype.Void, threadsafe=False) XML_SetUserData = expat_external( @@ -363,7 +363,7 @@ # XXX is this always true? return rffi.cast(rffi.VOIDPP, parser)[0] XML_Parse = expat_external( - 'XML_Parse', [XML_Parser, rffi.CCHARP, rffi.INT, rffi.INT], rffi.INT) + 'XML_Parse', [XML_Parser, rffi.CONST_CCHARP, rffi.INT, rffi.INT], rffi.INT) XML_StopParser = expat_external( 'XML_StopParser', [XML_Parser, rffi.INT], lltype.Void) @@ -374,7 +374,7 @@ XML_SetParamEntityParsing = expat_external( 'XML_SetParamEntityParsing', [XML_Parser, rffi.INT], lltype.Void) XML_SetBase = expat_external( - 'XML_SetBase', [XML_Parser, rffi.CCHARP], lltype.Void) + 'XML_SetBase', [XML_Parser, rffi.CONST_CCHARP], lltype.Void) if XML_COMBINED_VERSION >= 19505: XML_UseForeignDTD = expat_external( 'XML_UseForeignDTD', [XML_Parser, rffi.INT], lltype.Void) @@ -383,7 +383,7 @@ 'XML_GetErrorCode', [XML_Parser], rffi.INT) XML_ErrorString = expat_external( 'XML_ErrorString', [rffi.INT], - rffi.CCHARP) + rffi.CONST_CCHARP) XML_GetCurrentLineNumber = expat_external( 'XML_GetCurrentLineNumber', [XML_Parser], rffi.INT) XML_GetErrorLineNumber = XML_GetCurrentLineNumber @@ -397,11 +397,11 @@ XML_FreeContentModel = expat_external( 'XML_FreeContentModel', [XML_Parser, lltype.Ptr(XML_Content)], lltype.Void) XML_ExternalEntityParserCreate = expat_external( - 'XML_ExternalEntityParserCreate', [XML_Parser, rffi.CCHARP, rffi.CCHARP], + 'XML_ExternalEntityParserCreate', [XML_Parser, rffi.CONST_CCHARP, rffi.CONST_CCHARP], XML_Parser) XML_ExpatVersion = expat_external( - 'XML_ExpatVersion', [], rffi.CCHARP) + 'XML_ExpatVersion', [], rffi.CONST_CCHARP) def get_expat_version(space): return space.wrap(rffi.charp2str(XML_ExpatVersion())) diff --git a/rpython/rlib/test/test_rlocale.py b/rpython/rlib/test/test_rlocale.py --- a/rpython/rlib/test/test_rlocale.py +++ b/rpython/rlib/test/test_rlocale.py @@ -39,6 +39,6 @@ def test_libintl(): if sys.platform != "darwin" or not sys.platform.startswith("linux"): py.test.skip("there is (maybe) no libintl here") - _gettext = external('gettext', [rffi.CCHARP], rffi.CCHARP) + _gettext = external('gettext', [rffi.CONST_CCHARP], rffi.CCHARP) res = _gettext("1234") assert rffi.charp2str(res) == "1234" diff --git a/rpython/rtyper/lltypesystem/test/test_rffi.py b/rpython/rtyper/lltypesystem/test/test_rffi.py --- a/rpython/rtyper/lltypesystem/test/test_rffi.py +++ b/rpython/rtyper/lltypesystem/test/test_rffi.py @@ -767,11 +767,11 @@ def test_ptradd(): data = "hello, world!" - a = lltype.malloc(ARRAY_OF_CHAR, len(data), flavor='raw') + a = lltype.malloc(CONST_CCHARP.TO, len(data), flavor='raw') for i in xrange(len(data)): a[i] = data[i] a2 = ptradd(a, 2) - assert lltype.typeOf(a2) == lltype.typeOf(a) == lltype.Ptr(ARRAY_OF_CHAR) + assert lltype.typeOf(a2) == lltype.typeOf(a) == CONST_CCHARP for i in xrange(len(data) - 2): assert a2[i] == a[i + 2] lltype.free(a, flavor='raw') From noreply at buildbot.pypy.org Fri Sep 13 08:34:32 2013 From: noreply at buildbot.pypy.org (amauryfa) Date: Fri, 13 Sep 2013 08:34:32 +0200 (CEST) Subject: [pypy-commit] pypy const-correctness: Progress Message-ID: <20130913063432.6E73C1C13FA@cobra.cs.uni-duesseldorf.de> Author: Amaury Forgeot d'Arc Branch: const-correctness Changeset: r66933:eece652b55e2 Date: 2013-09-11 17:22 +0200 http://bitbucket.org/pypy/pypy/changeset/eece652b55e2/ Log: Progress diff --git a/pypy/module/cpyext/api.py b/pypy/module/cpyext/api.py --- a/pypy/module/cpyext/api.py +++ b/pypy/module/cpyext/api.py @@ -70,16 +70,8 @@ _compilation_info_ = CConfig._compilation_info_ VA_LIST_P = rffi.VOIDP # rffi.COpaquePtr('va_list') -CONST_STRING = lltype.Ptr(lltype.Array(lltype.Char, - hints={'nolength': True}), - use_cache=False) -CONST_WSTRING = lltype.Ptr(lltype.Array(lltype.UniChar, - hints={'nolength': True}), - use_cache=False) -assert CONST_STRING is not rffi.CCHARP -assert CONST_STRING == rffi.CCHARP -assert CONST_WSTRING is not rffi.CWCHARP -assert CONST_WSTRING == rffi.CWCHARP +CONST_STRING = rffi.CONST_CCHARP +CONST_WSTRING = rffi.CONST_CWCHARP # FILE* interface FILEP = rffi.COpaquePtr('FILE') 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 @@ -20,10 +20,10 @@ PyMethodDef = cpython_struct( 'PyMethodDef', - [('ml_name', rffi.CCHARP), + [('ml_name', rffi.CONST_CCHARP), ('ml_meth', PyCFunction_typedef), ('ml_flags', rffi.INT_real), - ('ml_doc', rffi.CCHARP), + ('ml_doc', rffi.CONST_CCHARP), ]) PyCFunctionObjectStruct = cpython_struct( diff --git a/pypy/module/cpyext/stringobject.py b/pypy/module/cpyext/stringobject.py --- a/pypy/module/cpyext/stringobject.py +++ b/pypy/module/cpyext/stringobject.py @@ -140,7 +140,8 @@ # copy string buffer w_str = from_ref(space, ref) s = space.str_w(w_str) - ref_str.c_buffer = rffi.str2charp(s) + # remove 'const' modifier + ref_str.c_buffer = rffi.cast(rffi.CCHARP, rffi.str2charp(s)) return ref_str.c_buffer @cpython_api([PyObject, rffi.CCHARPP, rffi.CArrayPtr(Py_ssize_t)], rffi.INT_real, error=-1) @@ -153,7 +154,8 @@ # copy string buffer w_str = from_ref(space, ref) s = space.str_w(w_str) - ref_str.c_buffer = rffi.str2charp(s) + # remove 'const' modifier + ref_str.c_buffer = rffi.cast(rffi.CCHARP, rffi.str2charp(s)) buffer[0] = ref_str.c_buffer if length: length[0] = ref_str.c_size diff --git a/pypy/module/cpyext/typeobjectdefs.py b/pypy/module/cpyext/typeobjectdefs.py --- a/pypy/module/cpyext/typeobjectdefs.py +++ b/pypy/module/cpyext/typeobjectdefs.py @@ -160,7 +160,7 @@ PyTypeObjectFields = [] PyTypeObjectFields.extend(PyVarObjectFields) PyTypeObjectFields.extend([ - ("tp_name", rffi.CCHARP), #E For printing, in format "." + ("tp_name", rffi.CONST_CCHARP), #E For printing, in format "." ("tp_basicsize", Py_ssize_t), #E For allocation ("tp_itemsize", Py_ssize_t), #E " diff --git a/pypy/module/crypt/interp_crypt.py b/pypy/module/crypt/interp_crypt.py --- a/pypy/module/crypt/interp_crypt.py +++ b/pypy/module/crypt/interp_crypt.py @@ -7,7 +7,7 @@ eci = ExternalCompilationInfo() else: eci = ExternalCompilationInfo(libraries=['crypt']) -c_crypt = rffi.llexternal('crypt', [rffi.CCHARP, rffi.CCHARP], rffi.CCHARP, +c_crypt = rffi.llexternal('crypt', [rffi.CONST_CCHARP, rffi.CONST_CCHARP], rffi.CCHARP, compilation_info=eci, threadsafe=False) @unwrap_spec(word=str, salt=str) 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 @@ -2,7 +2,7 @@ from rpython.rtyper.lltypesystem import rffi from rpython.rtyper.lltypesystem import lltype from rpython.rtyper.tool import rffi_platform as platform -from rpython.rtyper.lltypesystem.rffi import CCHARP +from rpython.rtyper.lltypesystem.rffi import CCHARP, CONST_CCHARP from rpython.translator.tool.cbuild import ExternalCompilationInfo from rpython.translator.platform import platform as target_platform @@ -487,7 +487,7 @@ socketconnect = external('connect', [socketfd_type, sockaddr_ptr, socklen_t], rffi.INT) -getaddrinfo = external('getaddrinfo', [CCHARP, CCHARP, +getaddrinfo = external('getaddrinfo', [CONST_CCHARP, CONST_CCHARP, addrinfo_ptr, lltype.Ptr(rffi.CArray(addrinfo_ptr))], rffi.INT) freeaddrinfo = external('freeaddrinfo', [addrinfo_ptr], lltype.Void) @@ -500,13 +500,13 @@ ntohs = external('ntohs', [rffi.USHORT], rffi.USHORT, threadsafe=False) if _POSIX: - inet_aton = external('inet_aton', [CCHARP, lltype.Ptr(in_addr)], + inet_aton = external('inet_aton', [CONST_CCHARP, lltype.Ptr(in_addr)], rffi.INT) inet_ntoa = external('inet_ntoa', [in_addr], rffi.CCHARP) if _POSIX: - inet_pton = external('inet_pton', [rffi.INT, rffi.CCHARP, + inet_pton = external('inet_pton', [rffi.INT, rffi.CONST_CCHARP, rffi.VOIDP], rffi.INT) inet_ntop = external('inet_ntop', [rffi.INT, rffi.VOIDP, CCHARP, @@ -537,12 +537,12 @@ sockaddr_ptr, socklen_t], ssize_t) socketshutdown = external('shutdown', [socketfd_type, rffi.INT], rffi.INT) gethostname = external('gethostname', [rffi.CCHARP, rffi.INT], rffi.INT) -gethostbyname = external('gethostbyname', [rffi.CCHARP], +gethostbyname = external('gethostbyname', [rffi.CONST_CCHARP], lltype.Ptr(cConfig.hostent)) gethostbyaddr = external('gethostbyaddr', [rffi.VOIDP, rffi.INT, rffi.INT], lltype.Ptr(cConfig.hostent)) -getservbyname = external('getservbyname', [rffi.CCHARP, rffi.CCHARP], lltype.Ptr(cConfig.servent)) -getservbyport = external('getservbyport', [rffi.INT, rffi.CCHARP], lltype.Ptr(cConfig.servent)) -getprotobyname = external('getprotobyname', [rffi.CCHARP], lltype.Ptr(cConfig.protoent)) +getservbyname = external('getservbyname', [rffi.CONST_CCHARP, rffi.CONST_CCHARP], lltype.Ptr(cConfig.servent)) +getservbyport = external('getservbyport', [rffi.INT, rffi.CONST_CCHARP], lltype.Ptr(cConfig.servent)) +getprotobyname = external('getprotobyname', [rffi.CONST_CCHARP], lltype.Ptr(cConfig.protoent)) if _POSIX: fcntl = external('fcntl', [socketfd_type, rffi.INT, rffi.INT], rffi.INT) diff --git a/rpython/rlib/rdynload.py b/rpython/rlib/rdynload.py --- a/rpython/rlib/rdynload.py +++ b/rpython/rlib/rdynload.py @@ -67,10 +67,10 @@ if not _WIN32: - c_dlopen = external('dlopen', [rffi.CCHARP, rffi.INT], rffi.VOIDP) + c_dlopen = external('dlopen', [rffi.CONST_CCHARP, rffi.INT], rffi.VOIDP) c_dlclose = external('dlclose', [rffi.VOIDP], rffi.INT, threadsafe=False) c_dlerror = external('dlerror', [], rffi.CCHARP) - c_dlsym = external('dlsym', [rffi.VOIDP, rffi.CCHARP], rffi.VOIDP) + c_dlsym = external('dlsym', [rffi.VOIDP, rffi.CONST_CCHARP], rffi.VOIDP) DLLHANDLE = rffi.VOIDP diff --git a/rpython/rlib/rlocale.py b/rpython/rlib/rlocale.py --- a/rpython/rlib/rlocale.py +++ b/rpython/rlib/rlocale.py @@ -182,7 +182,7 @@ sandboxsafe=True) -_setlocale = external('setlocale', [rffi.INT, rffi.CCHARP], rffi.CCHARP) +_setlocale = external('setlocale', [rffi.INT, rffi.CONST_CCHARP], rffi.CCHARP) def setlocale(category, locale): if cConfig.LC_MAX is not None: diff --git a/rpython/rlib/ropenssl.py b/rpython/rlib/ropenssl.py --- a/rpython/rlib/ropenssl.py +++ b/rpython/rlib/ropenssl.py @@ -185,9 +185,9 @@ lltype.Void) if HAVE_OPENSSL_RAND: - ssl_external('RAND_add', [rffi.CCHARP, rffi.INT, rffi.DOUBLE], lltype.Void) + ssl_external('RAND_add', [rffi.CONST_CCHARP, rffi.INT, rffi.DOUBLE], lltype.Void) ssl_external('RAND_status', [], rffi.INT) - ssl_external('RAND_egd', [rffi.CCHARP], rffi.INT) + ssl_external('RAND_egd', [rffi.CONST_CCHARP], rffi.INT) ssl_external('SSL_CTX_new', [SSL_METHOD], SSL_CTX) ssl_external('SSL_get_SSL_CTX', [SSL], SSL_CTX) ssl_external('TLSv1_method', [], SSL_METHOD) @@ -289,7 +289,7 @@ ssl_external('CRYPTO_free', [rffi.VOIDP], lltype.Void) libssl_OPENSSL_free = libssl_CRYPTO_free -ssl_external('SSL_write', [SSL, rffi.CCHARP, rffi.INT], rffi.INT) +ssl_external('SSL_write', [SSL, rffi.CONST_CCHARP, rffi.INT], rffi.INT) ssl_external('SSL_pending', [SSL], rffi.INT) ssl_external('SSL_read', [SSL, rffi.CCHARP, rffi.INT], rffi.INT) @@ -312,7 +312,7 @@ 'OpenSSL_add_all_digests', [], lltype.Void) EVP_get_digestbyname = external( 'EVP_get_digestbyname', - [rffi.CCHARP], EVP_MD) + [rffi.CONST_CCHARP], EVP_MD) EVP_DigestInit = external( 'EVP_DigestInit', [EVP_MD_CTX, EVP_MD], rffi.INT) diff --git a/rpython/rlib/rzlib.py b/rpython/rlib/rzlib.py --- a/rpython/rlib/rzlib.py +++ b/rpython/rlib/rzlib.py @@ -128,7 +128,7 @@ rffi.INT, # window bits rffi.INT, # mem level rffi.INT, # strategy - rffi.CCHARP, # version + rffi.CONST_CCHARP, # version rffi.INT], # stream size rffi.INT) _deflate = zlib_external('deflate', [z_stream_p, rffi.INT], rffi.INT) @@ -147,7 +147,7 @@ 'inflateInit2_', [z_stream_p, # stream rffi.INT, # window bits - rffi.CCHARP, # version + rffi.CONST_CCHARP, # version rffi.INT], # stream size rffi.INT) _inflate = zlib_external('inflate', [z_stream_p, rffi.INT], rffi.INT) 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 @@ -326,6 +326,7 @@ return get_ctypes_type(FIELDTYPE) def get_ctypes_type(T, delayed_builders=None, cannot_delay=False): + T = lltype.remove_const(T) # XXX Do we care? # Check delayed builders if cannot_delay and delayed_builders: for T2, builder in delayed_builders: diff --git a/rpython/rtyper/lltypesystem/lltype.py b/rpython/rtyper/lltypesystem/lltype.py --- a/rpython/rtyper/lltypesystem/lltype.py +++ b/rpython/rtyper/lltypesystem/lltype.py @@ -1212,7 +1212,7 @@ if field_name in self._T._flds: T1 = self._T._flds[field_name] T2 = typeOf(val) - if T1 == T2: + if isConvertibleFrom(T1, T2): setattr(self._obj, field_name, val) else: raise TypeError("%r instance field %r:\n" From noreply at buildbot.pypy.org Fri Sep 13 10:14:50 2013 From: noreply at buildbot.pypy.org (bivab) Date: Fri, 13 Sep 2013 10:14:50 +0200 (CEST) Subject: [pypy-commit] buildbot default: wrap link in a div Message-ID: <20130913081450.402D11C0E26@cobra.cs.uni-duesseldorf.de> Author: David Schneider Branch: Changeset: r863:40a9f6f46cdf Date: 2013-09-13 10:14 +0200 http://bitbucket.org/pypy/buildbot/changeset/40a9f6f46cdf/ Log: wrap link in a div diff --git a/master/templates/build.html b/master/templates/build.html --- a/master/templates/build.html +++ b/master/templates/build.html @@ -9,8 +9,9 @@ Build #{{ b.getNumber() }} -   (view in summary) - +
    {% if not b.isFinished() %} From noreply at buildbot.pypy.org Fri Sep 13 11:46:09 2013 From: noreply at buildbot.pypy.org (arigo) Date: Fri, 13 Sep 2013 11:46:09 +0200 (CEST) Subject: [pypy-commit] extradoc extradoc: Talk abstract, first version Message-ID: <20130913094609.E23AC1C0E26@cobra.cs.uni-duesseldorf.de> Author: Armin Rigo Branch: extradoc Changeset: r5048:ae5100082b6f Date: 2013-09-13 11:45 +0200 http://bitbucket.org/pypy/extradoc/changeset/ae5100082b6f/ Log: Talk abstract, first version diff --git a/talk/pycon2014/talk.rst b/talk/pycon2014/talk.rst new file mode 100644 --- /dev/null +++ b/talk/pycon2014/talk.rst @@ -0,0 +1,15 @@ +The status of PyPy +================== + +PyPy is an alternative Python interpreter. It is seriously fast, but +progress purely in that direction is reaching limits. Instead, it is +growing support for a larger part of the Python ecosystem: a long list +of common libraries are going from "unsupported" to "badly supported" to +"well supported". We also have beta Python 3 support. In short, try +PyPy today :-) + +On the research front, Transactional Memory seems to work as a way to +run programs on multiple cores. It is coming along, fully integrated +with the JIT compiler. We will show various examples, including +versions of event libraries (like Twisted, Tornado, greenlet...) that +run existing non-multithreaded programs on multiple cores. From noreply at buildbot.pypy.org Fri Sep 13 15:35:28 2013 From: noreply at buildbot.pypy.org (arigo) Date: Fri, 13 Sep 2013 15:35:28 +0200 (CEST) Subject: [pypy-commit] extradoc extradoc: PyCon ZA abstract Message-ID: <20130913133528.2C44A1C0E26@cobra.cs.uni-duesseldorf.de> Author: Armin Rigo Branch: extradoc Changeset: r5049:6874a5459934 Date: 2013-09-13 15:35 +0200 http://bitbucket.org/pypy/extradoc/changeset/6874a5459934/ Log: PyCon ZA abstract diff --git a/talk/pyconza2013/abstract.rst b/talk/pyconza2013/abstract.rst new file mode 100644 --- /dev/null +++ b/talk/pyconza2013/abstract.rst @@ -0,0 +1,23 @@ +Software Transactional Memory with PyPy +--------------------------------------- + +PyPy is a fast alternative Python implementation. Software +Transactional Memory is a current academic research topic. Put the two +together --brew for a couple of years-- and we obtain a version of PyPy +that runs on multiple cores, without the infamous Global Interpreter +Lock (GIL). It has been freshly released in beta, including integration +with the Just-in-Time compiler. + +But its point is not only of being "GIL-less": it can give the illusion +of single-threaded programming. I will give examples of what I mean +exactly by that. Starting from the usual multithreaded demos, I will +move to other examples where the actual threads are hidden to the +programmer. I will explain how we can modify the core of async +libraries (Twisted, Tornado, gevent, ...) to use multiples threads, +without exposing any concurrency issues to the user of the library --- +the existing Twisted/etc. programs still run mostly without change. + +I will also give an overview of how things work under the cover: the +10000-feet view is to create internally copies of objects and write +changes into these copies. This allows the originals to continue being +used by other threads. From noreply at buildbot.pypy.org Fri Sep 13 15:47:22 2013 From: noreply at buildbot.pypy.org (arigo) Date: Fri, 13 Sep 2013 15:47:22 +0200 (CEST) Subject: [pypy-commit] extradoc extradoc: Restart, putting more focus on STM and less on the Status of PyPy part Message-ID: <20130913134722.2640B1C0E26@cobra.cs.uni-duesseldorf.de> Author: Armin Rigo Branch: extradoc Changeset: r5050:b29cb4d623f0 Date: 2013-09-13 15:47 +0200 http://bitbucket.org/pypy/extradoc/changeset/b29cb4d623f0/ Log: Restart, putting more focus on STM and less on the Status of PyPy part diff --git a/talk/pycon2014/abstract.rst b/talk/pycon2014/abstract.rst new file mode 100644 --- /dev/null +++ b/talk/pycon2014/abstract.rst @@ -0,0 +1,34 @@ +Software Transactional Memory with PyPy +======================================= + +Description +----------- + +PyPy is a fast alternative Python implementation. Software +Transactional Memory is a current academic research topic. Put the two +together --brew for a couple of years-- and we obtain a version of PyPy +that runs on multiple cores, without the infamous Global Interpreter +Lock (GIL). It has been freshly released in beta, including integration +with the Just-in-Time compiler. + +The talk will also include a "general status of PyPy" part. + + +Audience +-------- + + +Objectives +---------- + + +Detailed abstract +----------------- + + +Outline +------- + + +Additional notes +---------------- diff --git a/talk/pycon2014/talk.rst b/talk/pycon2014/talk.rst deleted file mode 100644 --- a/talk/pycon2014/talk.rst +++ /dev/null @@ -1,15 +0,0 @@ -The status of PyPy -================== - -PyPy is an alternative Python interpreter. It is seriously fast, but -progress purely in that direction is reaching limits. Instead, it is -growing support for a larger part of the Python ecosystem: a long list -of common libraries are going from "unsupported" to "badly supported" to -"well supported". We also have beta Python 3 support. In short, try -PyPy today :-) - -On the research front, Transactional Memory seems to work as a way to -run programs on multiple cores. It is coming along, fully integrated -with the JIT compiler. We will show various examples, including -versions of event libraries (like Twisted, Tornado, greenlet...) that -run existing non-multithreaded programs on multiple cores. From noreply at buildbot.pypy.org Fri Sep 13 17:23:45 2013 From: noreply at buildbot.pypy.org (arigo) Date: Fri, 13 Sep 2013 17:23:45 +0200 (CEST) Subject: [pypy-commit] extradoc extradoc: Fill in the PyCon'14 abstract. Message-ID: <20130913152345.BCC5D1C12F0@cobra.cs.uni-duesseldorf.de> Author: Armin Rigo Branch: extradoc Changeset: r5051:ab66660420aa Date: 2013-09-13 17:23 +0200 http://bitbucket.org/pypy/extradoc/changeset/ab66660420aa/ Log: Fill in the PyCon'14 abstract. diff --git a/talk/pycon2014/abstract.rst b/talk/pycon2014/abstract.rst --- a/talk/pycon2014/abstract.rst +++ b/talk/pycon2014/abstract.rst @@ -8,27 +8,71 @@ Transactional Memory is a current academic research topic. Put the two together --brew for a couple of years-- and we obtain a version of PyPy that runs on multiple cores, without the infamous Global Interpreter -Lock (GIL). It has been freshly released in beta, including integration -with the Just-in-Time compiler. - -The talk will also include a "general status of PyPy" part. +Lock (GIL). It has been released last year in beta, including +integration with the Just-in-Time compiler. Audience -------- +People interested in PyPy; people looking for concurrency solutions. + Objectives ---------- +Attendees will learn about a way to use multiple cores in their +applications, and how it differs from the 'multiprocessing' package. + Detailed abstract ----------------- +A special version of PyPy runs on multiple cores, without the infamous +Global Interpreter Lock (GIL). It means it can run a single program +using multiple cores, rather than being limited to one core, like it +is the case for CPU-intensive programs on CPython. + +But the point is not only that: it can give the illusion of +single-threaded programming, even when you really want the program to +use multiple cores. I will give examples of what I mean exactly by +that. Starting from the usual multithreaded demos --with explicit +threads-- I will move to other examples where the actual threads are +hidden to the programmer. I will explain how we can modify/have +modified the core of async libraries (Twisted, Tornado, gevent, ...) to +use multiples threads, without exposing any concurrency issues to the +user of the library --- the existing Twisted/etc. programs still run +mostly without change. Depending on the status at the time of the +presentation, I will give demos of this, explaining in detail what +people can expect to have to change (very little), and how it performs +on real applications. + +I will give a comparison with the alternatives, foremost of which is the +stdlib 'multiprocessing' package. + +I will also give an overview of how things work under the cover: the +10000-feet view is to create internally copies of objects and write +changes into these copies. This allows the originals to continue being +used by other threads. It is an adaptation of previous work on +Software Transactional Memory (STM), notably RSTM. + Outline ------- +1. Intro (5 min): PyPy, STM + +2. Examples and demos (10 min): simple multithreading; atomic + multithreading; Twisted/etc. model; performance numbers. + +3. Comparison (5 min): independent processes; multiprocessing; custom + solutions. + +4. How things work under the cover (5 min): overview. + Additional notes ---------------- + +* Follow the progress of STM in PyPy: + http://morepypy.blogspot.ch/search/label/stm From noreply at buildbot.pypy.org Fri Sep 13 17:31:52 2013 From: noreply at buildbot.pypy.org (arigo) Date: Fri, 13 Sep 2013 17:31:52 +0200 (CEST) Subject: [pypy-commit] extradoc extradoc: updates Message-ID: <20130913153152.6066C1C12F0@cobra.cs.uni-duesseldorf.de> Author: Armin Rigo Branch: extradoc Changeset: r5052:a2c650a3ebb6 Date: 2013-09-13 17:31 +0200 http://bitbucket.org/pypy/extradoc/changeset/a2c650a3ebb6/ Log: updates diff --git a/talk/pycon2014/abstract.rst b/talk/pycon2014/abstract.rst --- a/talk/pycon2014/abstract.rst +++ b/talk/pycon2014/abstract.rst @@ -8,7 +8,7 @@ Transactional Memory is a current academic research topic. Put the two together --brew for a couple of years-- and we obtain a version of PyPy that runs on multiple cores, without the infamous Global Interpreter -Lock (GIL). It has been released last year in beta, including +Lock (GIL). It has been released in 2013 in beta, including integration with the Just-in-Time compiler. @@ -22,33 +22,35 @@ ---------- Attendees will learn about a way to use multiple cores in their -applications, and how it differs from the 'multiprocessing' package. +applications, and how it differs from other solutions like the +'multiprocessing' package. Detailed abstract ----------------- -A special version of PyPy runs on multiple cores, without the infamous -Global Interpreter Lock (GIL). It means it can run a single program -using multiple cores, rather than being limited to one core, like it -is the case for CPU-intensive programs on CPython. +pypy-stm is a special version of PyPy that runs on multiple cores +without the infamous Global Interpreter Lock (GIL). It means that it +can run a single Python program using multiple cores, rather than being +limited to one core, as is the case for CPU-intensive programs on +CPython. -But the point is not only that: it can give the illusion of -single-threaded programming, even when you really want the program to -use multiple cores. I will give examples of what I mean exactly by -that. Starting from the usual multithreaded demos --with explicit -threads-- I will move to other examples where the actual threads are -hidden to the programmer. I will explain how we can modify/have -modified the core of async libraries (Twisted, Tornado, gevent, ...) to -use multiples threads, without exposing any concurrency issues to the -user of the library --- the existing Twisted/etc. programs still run -mostly without change. Depending on the status at the time of the -presentation, I will give demos of this, explaining in detail what -people can expect to have to change (very little), and how it performs -on real applications. +But the point is not only that: it can give the programmer the illusion +of single-threaded programming, even when he really wants the program to +use multiple cores. This naturally avoids a whole class of bugs. I +will give examples of what I mean exactly by that. Starting from the +usual multithreaded demos --with explicit threads-- I will move to other +examples where the actual threads are hidden to the programmer. I will +explain how we can modify/have modified the core of async libraries +(Twisted, Tornado, gevent, ...) to use multiples threads, without +exposing any concurrency issues to the user of the library --- the +existing Twisted/etc. programs still run mostly without change. +Depending on the status at the time of the presentation, I will give +demos of this, explaining in detail what people can expect to have to +change (very little), and how it performs on real applications. -I will give a comparison with the alternatives, foremost of which is the -stdlib 'multiprocessing' package. +I will give a comparison with the alternative approaches: independent +processes; the stdlib 'multiprocessing' package; or custom solutions. I will also give an overview of how things work under the cover: the 10000-feet view is to create internally copies of objects and write @@ -70,6 +72,8 @@ 4. How things work under the cover (5 min): overview. +5. Questions (5 min). + Additional notes ---------------- From noreply at buildbot.pypy.org Fri Sep 13 17:40:25 2013 From: noreply at buildbot.pypy.org (arigo) Date: Fri, 13 Sep 2013 17:40:25 +0200 (CEST) Subject: [pypy-commit] extradoc extradoc: more updates Message-ID: <20130913154025.E863C1C0E26@cobra.cs.uni-duesseldorf.de> Author: Armin Rigo Branch: extradoc Changeset: r5053:6ce8d68dceb0 Date: 2013-09-13 17:40 +0200 http://bitbucket.org/pypy/extradoc/changeset/6ce8d68dceb0/ Log: more updates diff --git a/talk/pycon2014/abstract.rst b/talk/pycon2014/abstract.rst --- a/talk/pycon2014/abstract.rst +++ b/talk/pycon2014/abstract.rst @@ -29,22 +29,22 @@ Detailed abstract ----------------- -pypy-stm is a special version of PyPy that runs on multiple cores +'pypy-stm' is a special version of PyPy that runs on multiple cores without the infamous Global Interpreter Lock (GIL). It means that it can run a single Python program using multiple cores, rather than being -limited to one core, as is the case for CPU-intensive programs on -CPython. +limited to one core, as it is the case for CPU-intensive programs on +CPython (or regular PyPy). -But the point is not only that: it can give the programmer the illusion -of single-threaded programming, even when he really wants the program to -use multiple cores. This naturally avoids a whole class of bugs. I -will give examples of what I mean exactly by that. Starting from the -usual multithreaded demos --with explicit threads-- I will move to other -examples where the actual threads are hidden to the programmer. I will -explain how we can modify/have modified the core of async libraries -(Twisted, Tornado, gevent, ...) to use multiples threads, without -exposing any concurrency issues to the user of the library --- the -existing Twisted/etc. programs still run mostly without change. +But the point is not only that: this approach can give the programmer +the illusion of single-threaded programming, even when he really wants +the program to use multiple cores. This naturally avoids a whole class +of bugs. I will give examples of what I mean exactly by that. Starting +from the usual multithreaded demos --with explicit threads-- I will move +to other examples where the actual threads are hidden to the programmer. +I will explain how we can modify/have modified the core of async +libraries (Twisted, Tornado, gevent, ...) to use multiples threads, +without exposing any concurrency issues to the user of the library --- +the existing Twisted/etc. programs still run mostly without change. Depending on the status at the time of the presentation, I will give demos of this, explaining in detail what people can expect to have to change (very little), and how it performs on real applications. @@ -64,8 +64,8 @@ 1. Intro (5 min): PyPy, STM -2. Examples and demos (10 min): simple multithreading; atomic - multithreading; Twisted/etc. model; performance numbers. +2. Examples and demos (10 min): simple multithreading; multithreading + with atomic sections; Twisted/etc. model; performance numbers. 3. Comparison (5 min): independent processes; multiprocessing; custom solutions. From noreply at buildbot.pypy.org Fri Sep 13 17:41:56 2013 From: noreply at buildbot.pypy.org (amauryfa) Date: Fri, 13 Sep 2013 17:41:56 +0200 (CEST) Subject: [pypy-commit] pypy const-correctness: Fixes Message-ID: <20130913154156.E00AC1C0E26@cobra.cs.uni-duesseldorf.de> Author: Amaury Forgeot d'Arc Branch: const-correctness Changeset: r66936:835ebb42f42e Date: 2013-09-13 17:40 +0200 http://bitbucket.org/pypy/pypy/changeset/835ebb42f42e/ Log: Fixes 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 @@ -33,7 +33,7 @@ return rffi.llexternal(name, args, result, compilation_info=eci, **kwargs) c_getpwuid = external("getpwuid", [uid_t], passwd_p) -c_getpwnam = external("getpwnam", [rffi.CCHARP], passwd_p) +c_getpwnam = external("getpwnam", [rffi.CONST_CCHARP], passwd_p) c_setpwent = external("setpwent", [], lltype.Void) c_getpwent = external("getpwent", [], passwd_p) c_endpwent = external("endpwent", [], lltype.Void) 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 @@ -194,7 +194,7 @@ c_get_daylight = external('pypy_get_daylight', [], rffi.INT, win_eci) c_get_tzname = external('pypy_get_tzname', [], rffi.CCHARPP, win_eci) -c_strftime = external('strftime', [rffi.CCHARP, rffi.SIZE_T, rffi.CCHARP, TM_P], +c_strftime = external('strftime', [rffi.CCHARP, rffi.SIZE_T, rffi.CONST_CCHARP, TM_P], rffi.SIZE_T) def _init_accept2dyear(space): From noreply at buildbot.pypy.org Fri Sep 13 17:41:58 2013 From: noreply at buildbot.pypy.org (amauryfa) Date: Fri, 13 Sep 2013 17:41:58 +0200 (CEST) Subject: [pypy-commit] pypy const-correctness: hg merge default Message-ID: <20130913154158.68D9F1C0E26@cobra.cs.uni-duesseldorf.de> Author: Amaury Forgeot d'Arc Branch: const-correctness Changeset: r66937:eb449cec3ef8 Date: 2013-09-13 17:41 +0200 http://bitbucket.org/pypy/pypy/changeset/eb449cec3ef8/ Log: hg merge default diff --git a/lib-python/2.7/argparse.py b/lib-python/2.7/argparse.py --- a/lib-python/2.7/argparse.py +++ b/lib-python/2.7/argparse.py @@ -1780,7 +1780,19 @@ # error if this argument is not allowed with other previously # seen arguments, assuming that actions that use the default # value don't really count as "present" - if argument_values is not action.default: + + # XXX PyPy bug-to-bug compatibility: "is" on primitive types + # is not consistent in CPython. We'll assume it is close + # enough for ints (which is true only for "small ints"), but + # for floats and longs and complexes we'll go for the option + # of forcing "is" to say False, like it usually does on + # CPython. A fix is pending on CPython trunk + # (http://bugs.python.org/issue18943) but that might change + # the details of the semantics and so not be applied to 2.7. + # See the line AA below. + + if (argument_values is not action.default or + type(argument_values) in (float, long, complex)): # AA seen_non_default_actions.add(action) for conflict_action in action_conflicts.get(action, []): if conflict_action in seen_non_default_actions: diff --git a/pypy/module/thread/test/test_thread.py b/pypy/module/thread/test/test_thread.py --- a/pypy/module/thread/test/test_thread.py +++ b/pypy/module/thread/test/test_thread.py @@ -187,9 +187,12 @@ skip("this OS supports too many threads to check (> 1000)") lock = thread.allocate_lock() lock.acquire() + count = [0] def f(): + count[0] += 1 lock.acquire() lock.release() + count[0] -= 1 try: try: for i in range(1000): @@ -197,11 +200,15 @@ finally: lock.release() # wait a bit to allow most threads to finish now - self.busywait(2.0) + while count[0] > 10: + print count[0] # <- releases the GIL + print "ok." except (thread.error, MemoryError): pass else: raise Exception("could unexpectedly start 1000 threads") + # safety: check that we can start a new thread here + thread.start_new_thread(lambda: None, ()) def test_stack_size(self): import thread diff --git a/rpython/jit/codewriter/call.py b/rpython/jit/codewriter/call.py --- a/rpython/jit/codewriter/call.py +++ b/rpython/jit/codewriter/call.py @@ -92,17 +92,6 @@ else: assert op.opname == 'indirect_call' graphs = op.args[-1].value - if graphs is None: - # special case: handle the indirect call that goes to - # the 'instantiate' methods. This check is a bit imprecise - # but it's not too bad if we mistake a random indirect call - # for the one to 'instantiate'. - from rpython.rtyper.lltypesystem import rclass - CALLTYPE = op.args[0].concretetype - if (op.opname == 'indirect_call' and len(op.args) == 2 and - CALLTYPE == rclass.OBJECT_VTABLE.instantiate): - graphs = list(self._graphs_of_all_instantiate()) - # if graphs is not None: result = [] for graph in graphs: @@ -114,11 +103,6 @@ # residual call case: we don't need to look into any graph return None - def _graphs_of_all_instantiate(self): - for vtable in self.rtyper.lltype2vtable.values(): - if vtable.instantiate: - yield vtable.instantiate._obj.graph - def guess_call_kind(self, op, is_candidate=None): if op.opname == 'direct_call': funcptr = op.args[0].value 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 @@ -166,9 +166,6 @@ 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/test/test_ajit.py b/rpython/jit/metainterp/test/test_ajit.py --- a/rpython/jit/metainterp/test/test_ajit.py +++ b/rpython/jit/metainterp/test/test_ajit.py @@ -1411,7 +1411,6 @@ self.check_resops(call=2) def test_merge_guardclass_guardvalue(self): - from rpython.rlib.objectmodel import instantiate myjitdriver = JitDriver(greens = [], reds = ['x', 'l']) class A(object): @@ -1438,7 +1437,6 @@ self.check_resops(guard_class=0, guard_value=6) def test_merge_guardnonnull_guardclass(self): - from rpython.rlib.objectmodel import instantiate myjitdriver = JitDriver(greens = [], reds = ['x', 'l']) class A(object): @@ -1468,7 +1466,6 @@ def test_merge_guardnonnull_guardvalue(self): - from rpython.rlib.objectmodel import instantiate myjitdriver = JitDriver(greens = [], reds = ['x', 'l']) class A(object): @@ -1497,7 +1494,6 @@ def test_merge_guardnonnull_guardvalue_2(self): - from rpython.rlib.objectmodel import instantiate myjitdriver = JitDriver(greens = [], reds = ['x', 'l']) class A(object): @@ -1526,7 +1522,6 @@ def test_merge_guardnonnull_guardclass_guardvalue(self): - from rpython.rlib.objectmodel import instantiate myjitdriver = JitDriver(greens = [], reds = ['x', 'l']) class A(object): diff --git a/rpython/rlib/rsre/rpy/__init__.py b/rpython/rlib/rsre/rpy/__init__.py new file mode 100644 --- /dev/null +++ b/rpython/rlib/rsre/rpy/__init__.py @@ -0,0 +1,1 @@ +from ._sre import get_code diff --git a/rpython/rlib/rsre/rpy.py b/rpython/rlib/rsre/rpy/_sre.py rename from rpython/rlib/rsre/rpy.py rename to rpython/rlib/rsre/rpy/_sre.py --- a/rpython/rlib/rsre/rpy.py +++ b/rpython/rlib/rsre/rpy/_sre.py @@ -1,46 +1,24 @@ from rpython.rlib.rsre import rsre_char -from rpython.rlib.rsre.rsre_core import match from rpython.rlib.rarithmetic import intmask -def get_hacked_sre_compile(my_compile): - """Return a copy of the sre_compile module for which the _sre - module is a custom module that has _sre.compile == my_compile - and CODESIZE == rsre_char.CODESIZE. - """ - import sre_compile, sre_constants, __builtin__, new - sre_hacked = new.module("_sre_hacked") - sre_hacked.compile = my_compile - sre_hacked.MAGIC = sre_compile.MAGIC - sre_hacked.CODESIZE = rsre_char.CODESIZE - sre_hacked.MAXREPEAT = sre_constants.MAX_REPEAT - sre_hacked.getlower = rsre_char.getlower - def my_import(name, *args): - if name == '_sre': - return sre_hacked - else: - return default_import(name, *args) - src = sre_compile.__file__ - if src.lower().endswith('.pyc') or src.lower().endswith('.pyo'): - src = src[:-1] - mod = new.module("sre_compile_hacked") - default_import = __import__ - try: - __builtin__.__import__ = my_import - execfile(src, mod.__dict__) - finally: - __builtin__.__import__ = default_import - return mod + +MAGIC = 20031017 +CODESIZE = rsre_char.CODESIZE +getlower = rsre_char.getlower + class GotIt(Exception): pass -def my_compile(pattern, flags, code, *args): + +def compile(pattern, flags, code, *args): raise GotIt([intmask(i) for i in code], flags, args) -sre_compile_hacked = get_hacked_sre_compile(my_compile) + def get_code(regexp, flags=0, allargs=False): + from . import sre_compile try: - sre_compile_hacked.compile(regexp, flags) + sre_compile.compile(regexp, flags) except GotIt, e: pass else: diff --git a/lib-python/2.7/sre_compile.py b/rpython/rlib/rsre/rpy/sre_compile.py copy from lib-python/2.7/sre_compile.py copy to rpython/rlib/rsre/rpy/sre_compile.py --- a/lib-python/2.7/sre_compile.py +++ b/rpython/rlib/rsre/rpy/sre_compile.py @@ -8,11 +8,11 @@ # See the sre.py file for information on usage and redistribution. # -"""Internal support module for sre""" +"""Internal support module for sre (copied from CPython 2.7.3)""" -import _sre, sys -import sre_parse -from sre_constants import * +import sys +from . import _sre, sre_parse +from .sre_constants import * assert _sre.MAGIC == MAGIC, "SRE module mismatch" diff --git a/lib-python/2.7/sre_constants.py b/rpython/rlib/rsre/rpy/sre_constants.py copy from lib-python/2.7/sre_constants.py copy to rpython/rlib/rsre/rpy/sre_constants.py --- a/lib-python/2.7/sre_constants.py +++ b/rpython/rlib/rsre/rpy/sre_constants.py @@ -9,7 +9,7 @@ # See the sre.py file for information on usage and redistribution. # -"""Internal support module for sre""" +"""Internal support module for sre (copied from CPython 2.7.3)""" # update when constants are added or removed @@ -20,10 +20,8 @@ MAXREPEAT = 65535 # SRE standard exception (access as sre.error) -# should this really be here? - -class error(Exception): - pass +# (use the real re.error exception class) +from re import error # operators diff --git a/lib-python/2.7/sre_parse.py b/rpython/rlib/rsre/rpy/sre_parse.py copy from lib-python/2.7/sre_parse.py copy to rpython/rlib/rsre/rpy/sre_parse.py --- a/lib-python/2.7/sre_parse.py +++ b/rpython/rlib/rsre/rpy/sre_parse.py @@ -8,19 +8,13 @@ # See the sre.py file for information on usage and redistribution. # -"""Internal support module for sre""" +"""Internal support module for sre (copied from CPython 2.7.3)""" # XXX: show string offset and offending character for all errors import sys -from sre_constants import * - -try: - from __pypy__ import newdict -except ImportError: - assert '__pypy__' not in sys.builtin_module_names - newdict = lambda _ : {} +from .sre_constants import * SPECIAL_CHARS = ".\\[{()*+?^$|" REPEAT_CHARS = "*+?{" @@ -74,7 +68,7 @@ self.flags = 0 self.open = [] self.groups = 1 - self.groupdict = newdict("module") + self.groupdict = {} def opengroup(self, name=None): gid = self.groups self.groups = gid + 1 diff --git a/rpython/rlib/rsre/rsre_re.py b/rpython/rlib/rsre/rsre_re.py --- a/rpython/rlib/rsre/rsre_re.py +++ b/rpython/rlib/rsre/rsre_re.py @@ -286,8 +286,8 @@ class Scanner: # This class is copied directly from re.py. def __init__(self, lexicon, flags=0): - from sre_constants import BRANCH, SUBPATTERN - import sre_parse + from rpython.rlib.rsre.rpy.sre_constants import BRANCH, SUBPATTERN + from rpython.rlib.rsre.rpy import sre_parse self.lexicon = lexicon # combine phrases into a compound pattern p = [] diff --git a/rpython/rlib/rsre/test/test_char.py b/rpython/rlib/rsre/test/test_char.py --- a/rpython/rlib/rsre/test/test_char.py +++ b/rpython/rlib/rsre/test/test_char.py @@ -48,7 +48,7 @@ assert not rsre_char.is_uni_word(ord(',')) def test_category(): - from sre_constants import CHCODES + from rpython.rlib.rsre.rpy.sre_constants import CHCODES cat = rsre_char.category_dispatch # assert cat(CHCODES["category_digit"], ord('1')) diff --git a/rpython/rtyper/lltypesystem/rpbc.py b/rpython/rtyper/lltypesystem/rpbc.py --- a/rpython/rtyper/lltypesystem/rpbc.py +++ b/rpython/rtyper/lltypesystem/rpbc.py @@ -377,11 +377,20 @@ # no __init__ here, AbstractClassesPBCRepr.__init__ is good enough def _instantiate_runtime_class(self, hop, vtypeptr, r_instance): - v_instantiate = hop.genop('getfield', [vtypeptr, hop.inputconst(Void, "instantiate")], resulttype=vtypeptr.concretetype.TO.instantiate) - possible_graphs = hop.inputconst(Void, - [desc.getclassdef(None).my_instantiate_graph for desc in self.s_pbc.descriptions] - ) - v_inst = hop.genop('indirect_call', [v_instantiate, possible_graphs], resulttype=vtypeptr.concretetype.TO.instantiate.TO.RESULT) + graphs = [] + for desc in self.s_pbc.descriptions: + classdef = desc.getclassdef(None) + assert hasattr(classdef, 'my_instantiate_graph') + graphs.append(classdef.my_instantiate_graph) + c_graphs = hop.inputconst(Void, graphs) + # + # "my_instantiate = typeptr.instantiate" + c_name = hop.inputconst(Void, 'instantiate') + v_instantiate = hop.genop('getfield', [vtypeptr, c_name], + resulttype = rclass.OBJECT_VTABLE.instantiate) + # "my_instantiate()" + v_inst = hop.genop('indirect_call', [v_instantiate, c_graphs], + resulttype = rclass.OBJECTPTR) return hop.genop('cast_pointer', [v_inst], resulttype=r_instance) def getlowleveltype(self): diff --git a/rpython/rtyper/rbuiltin.py b/rpython/rtyper/rbuiltin.py --- a/rpython/rtyper/rbuiltin.py +++ b/rpython/rtyper/rbuiltin.py @@ -705,10 +705,6 @@ assert isinstance(hop.args_r[0], rclass.InstanceRepr) return hop.args_r[0].rtype_isinstance(hop) -def ll_instantiate(typeptr): # NB. used by rpbc.ClassesPBCRepr as well - my_instantiate = typeptr.instantiate - return my_instantiate() - def rtype_instantiate(hop): hop.exception_cannot_occur() s_class = hop.args_s[0] @@ -716,10 +712,9 @@ if len(s_class.descriptions) != 1: # instantiate() on a variable class vtypeptr, = hop.inputargs(rclass.get_type_repr(hop.rtyper)) - v_inst = hop.gendirectcall(ll_instantiate, vtypeptr) - return hop.genop('cast_pointer', [v_inst], # v_type implicit in r_result - resulttype = hop.r_result.lowleveltype) - + r_class = hop.args_r[0] + return r_class._instantiate_runtime_class(hop, vtypeptr, + hop.r_result.lowleveltype) classdef = s_class.any_description().getuniqueclassdef() return rclass.rtype_new_instance(hop.rtyper, classdef, hop.llops) diff --git a/rpython/translator/backendopt/gilanalysis.py b/rpython/translator/backendopt/gilanalysis.py --- a/rpython/translator/backendopt/gilanalysis.py +++ b/rpython/translator/backendopt/gilanalysis.py @@ -26,9 +26,6 @@ return False else: return False - - def analyze_instantiate_call(self, seen=None): - return False def analyze_simple_operation(self, op, graphinfo): return False diff --git a/rpython/translator/backendopt/graphanalyze.py b/rpython/translator/backendopt/graphanalyze.py --- a/rpython/translator/backendopt/graphanalyze.py +++ b/rpython/translator/backendopt/graphanalyze.py @@ -68,9 +68,6 @@ result, self.analyze_direct_call(graph, seen)) return result - def analyze_instantiate_call(self, seen=None): - return self.top_result() - def analyze_link(self, graph, link): return self.bottom_result() @@ -79,7 +76,7 @@ def compute_graph_info(self, graph): return None - def analyze(self, op, seen=None, graphinfo=None, block=None): + def analyze(self, op, seen=None, graphinfo=None): if op.opname == "direct_call": graph = get_graph(op.args[0], self.translator) if graph is None: @@ -94,18 +91,6 @@ elif op.opname == "indirect_call": graphs = op.args[-1].value if graphs is None: - if block is not None: - v_func = op.args[0] - for op1 in block.operations: - if (v_func is op1.result and - op1.opname == 'getfield' and - op1.args[0].concretetype == rclass.CLASSTYPE and - op1.args[1].value == 'instantiate'): - x = self.analyze_instantiate_call(seen) - if self.verbose and x: - self.dump_info('analyze_instantiate(%s): %r' % ( - graphs, x)) - return x if self.verbose: self.dump_info('%s to unknown' % (op,)) return self.top_result() @@ -143,7 +128,7 @@ for op in block.operations: result = self.add_to_result( result, - self.analyze(op, seen, graphinfo, block=block) + self.analyze(op, seen, graphinfo) ) if self.is_top_result(result): break @@ -177,7 +162,7 @@ graphs = self.translator.graphs for graph in graphs: for block, op in graph.iterblockops(): - self.analyze(op, block=block) + self.analyze(op) class Dependency(object): diff --git a/rpython/translator/backendopt/test/test_writeanalyze.py b/rpython/translator/backendopt/test/test_writeanalyze.py --- a/rpython/translator/backendopt/test/test_writeanalyze.py +++ b/rpython/translator/backendopt/test/test_writeanalyze.py @@ -169,8 +169,6 @@ assert not wa.analyze(op_call_m) def test_instantiate(self): - # instantiate is interesting, because it leads to one of the few cases of - # an indirect call without a list of graphs from rpython.rlib.objectmodel import instantiate class A: pass @@ -187,7 +185,7 @@ t, wa = self.translate(f, [int]) fgraph = graphof(t, f) result = wa.analyze(fgraph.startblock.operations[0]) - assert result is top_set + assert not result def test_llexternal(self): from rpython.rtyper.lltypesystem.rffi import llexternal From noreply at buildbot.pypy.org Fri Sep 13 18:02:45 2013 From: noreply at buildbot.pypy.org (arigo) Date: Fri, 13 Sep 2013 18:02:45 +0200 (CEST) Subject: [pypy-commit] extradoc extradoc: Integrate cfbolz's remark Message-ID: <20130913160245.738381C12F0@cobra.cs.uni-duesseldorf.de> Author: Armin Rigo Branch: extradoc Changeset: r5055:f310c0f719bf Date: 2013-09-13 18:02 +0200 http://bitbucket.org/pypy/extradoc/changeset/f310c0f719bf/ Log: Integrate cfbolz's remark diff --git a/talk/pyconza2013/abstract.rst b/talk/pyconza2013/abstract.rst --- a/talk/pyconza2013/abstract.rst +++ b/talk/pyconza2013/abstract.rst @@ -15,7 +15,8 @@ programmer. I will explain how the core of async libraries (Twisted, Tornado, gevent, ...) can be modified to use multiples threads, without exposing any concurrency issues to the user of the library --- -existing Twisted/etc. programs still run mostly without change. +existing Twisted/etc. programs still run correctly without change. +(They may need a few small changes to enable parallelism.) I will also give an overview of how things work under the cover: the 10000-feet view is to internally create copies of objects and write From noreply at buildbot.pypy.org Fri Sep 13 18:08:09 2013 From: noreply at buildbot.pypy.org (arigo) Date: Fri, 13 Sep 2013 18:08:09 +0200 (CEST) Subject: [pypy-commit] extradoc extradoc: Rephrase according to e2b99ea24c2f. Message-ID: <20130913160809.4D01C1C12F0@cobra.cs.uni-duesseldorf.de> Author: Armin Rigo Branch: extradoc Changeset: r5056:dd629bb8fa61 Date: 2013-09-13 18:07 +0200 http://bitbucket.org/pypy/extradoc/changeset/dd629bb8fa61/ Log: Rephrase according to e2b99ea24c2f. diff --git a/talk/pycon2014/abstract.rst b/talk/pycon2014/abstract.rst --- a/talk/pycon2014/abstract.rst +++ b/talk/pycon2014/abstract.rst @@ -35,25 +35,29 @@ limited to one core, as it is the case for CPU-intensive programs on CPython (or regular PyPy). -But the point is not only that: this approach can give the programmer -the illusion of single-threaded programming, even when he really wants -the program to use multiple cores. This naturally avoids a whole class -of bugs. I will give examples of what I mean exactly by that. Starting -from the usual multithreaded demos --with explicit threads-- I will move -to other examples where the actual threads are hidden to the programmer. -I will explain how we can modify/have modified the core of async -libraries (Twisted, Tornado, gevent, ...) to use multiples threads, -without exposing any concurrency issues to the user of the library --- -the existing Twisted/etc. programs still run mostly without change. -Depending on the status at the time of the presentation, I will give -demos of this, explaining in detail what people can expect to have to -change (very little), and how it performs on real applications. +But the point is not only that: this approach can also give the +programmer the illusion of single-threaded programming, even when he +really wants the program to use multiple cores. This naturally avoids a +whole class of bugs. I will give examples of what exactly I mean by +that. Starting from the usual multithreaded demos --with explicit +threads-- I will move to other examples where the actual threads are +hidden to the programmer. I will explain how the core of async +libraries (Twisted, Tornado, gevent, ...) can be/have been modified to +use multiples threads, without exposing any concurrency issues to the +user of the library --- existing Twisted/etc. programs still run +correctly without change. (They may need a few small changes to enable +parallelism.) -I will give a comparison with the alternative approaches: independent -processes; the stdlib 'multiprocessing' package; or custom solutions. +Depending on the status of pypy-stm at the time of the presentation, I +will give demos of this, explaining in detail what people can expect to +have to change (very little), and how it performs on real applications. + +I will then give a comparison with the alternative approaches: +independent processes; the stdlib 'multiprocessing' package; or custom +solutions. I will also give an overview of how things work under the cover: the -10000-feet view is to create internally copies of objects and write +10000-feet view is to internally create copies of objects and write changes into these copies. This allows the originals to continue being used by other threads. It is an adaptation of previous work on Software Transactional Memory (STM), notably RSTM. From noreply at buildbot.pypy.org Fri Sep 13 19:01:08 2013 From: noreply at buildbot.pypy.org (arigo) Date: Fri, 13 Sep 2013 19:01:08 +0200 (CEST) Subject: [pypy-commit] extradoc extradoc: Tweak Message-ID: <20130913170108.D953B1C0E26@cobra.cs.uni-duesseldorf.de> Author: Armin Rigo Branch: extradoc Changeset: r5058:a80fed801aa1 Date: 2013-09-13 19:00 +0200 http://bitbucket.org/pypy/extradoc/changeset/a80fed801aa1/ Log: Tweak diff --git a/talk/pycon2014/abstract.rst b/talk/pycon2014/abstract.rst --- a/talk/pycon2014/abstract.rst +++ b/talk/pycon2014/abstract.rst @@ -6,7 +6,7 @@ PyPy is a fast alternative Python implementation. Software Transactional Memory is a current academic research topic. Put the two -together --brew for a couple of years-- and we obtain a version of PyPy +together --brew for a couple of years-- and we get a version of PyPy that runs on multiple cores, without the infamous Global Interpreter Lock (GIL). It has been released in 2013 in beta, including integration with the Just-in-Time compiler. diff --git a/talk/pyconza2013/abstract.rst b/talk/pyconza2013/abstract.rst --- a/talk/pyconza2013/abstract.rst +++ b/talk/pyconza2013/abstract.rst @@ -3,7 +3,7 @@ PyPy is a fast alternative Python implementation. Software Transactional Memory is a current academic research topic. Put the two -together --brew for a couple of years-- and we obtain a version of PyPy +together --brew for a couple of years-- and we get a version of PyPy that runs on multiple cores, without the infamous Global Interpreter Lock (GIL). It has been freshly released in beta, including integration with the Just-in-Time compiler. From noreply at buildbot.pypy.org Fri Sep 13 20:10:25 2013 From: noreply at buildbot.pypy.org (amauryfa) Date: Fri, 13 Sep 2013 20:10:25 +0200 (CEST) Subject: [pypy-commit] pypy const-correctness: More fixes Message-ID: <20130913181025.0F2661C0E26@cobra.cs.uni-duesseldorf.de> Author: Amaury Forgeot d'Arc Branch: const-correctness Changeset: r66939:420c5addf795 Date: 2013-09-13 20:09 +0200 http://bitbucket.org/pypy/pypy/changeset/420c5addf795/ Log: More fixes 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 @@ -1257,7 +1257,7 @@ TYPE1 = lltype.typeOf(value) cvalue = lltype2ctypes(value) cresulttype = get_ctypes_type(RESTYPE) - if RESTYPE == TYPE1: + if lltype.isConvertibleFrom(RESTYPE, TYPE1): return value elif isinstance(TYPE1, lltype.Ptr): if isinstance(RESTYPE, lltype.Ptr): diff --git a/rpython/rtyper/lltypesystem/test/test_ll2ctypes.py b/rpython/rtyper/lltypesystem/test/test_ll2ctypes.py --- a/rpython/rtyper/lltypesystem/test/test_ll2ctypes.py +++ b/rpython/rtyper/lltypesystem/test/test_ll2ctypes.py @@ -229,7 +229,7 @@ def test_strlen(self): eci = ExternalCompilationInfo(includes=['string.h']) - strlen = rffi.llexternal('strlen', [rffi.CCHARP], rffi.SIZE_T, + strlen = rffi.llexternal('strlen', [rffi.CONST_CCHARP], rffi.SIZE_T, compilation_info=eci) s = rffi.str2charp("xxx") res = strlen(s) @@ -323,7 +323,7 @@ def test_strchr(self): eci = ExternalCompilationInfo(includes=['string.h']) - strchr = rffi.llexternal('strchr', [rffi.CCHARP, rffi.INT], + strchr = rffi.llexternal('strchr', [rffi.CONST_CCHARP, rffi.INT], rffi.CCHARP, compilation_info=eci) s = rffi.str2charp("hello world") res = strchr(s, ord('r')) @@ -390,7 +390,8 @@ def test_opaque_obj_2(self): FILEP = rffi.COpaquePtr('FILE') - fopen = rffi.llexternal('fopen', [rffi.CCHARP, rffi.CCHARP], FILEP) + fopen = rffi.llexternal('fopen', + [rffi.CONST_CCHARP, rffi.CONST_CCHARP], FILEP) fclose = rffi.llexternal('fclose', [FILEP], rffi.INT) tmppath = udir.join('test_ll2ctypes.test_opaque_obj_2') ll_file = fopen(str(tmppath), "w") @@ -479,7 +480,7 @@ assert not ALLOCATED # detects memory leaks in the test def test_funcptr2(self): - FUNCTYPE = lltype.FuncType([rffi.CCHARP], rffi.LONG) + FUNCTYPE = lltype.FuncType([rffi.CONST_CCHARP], rffi.LONG) cstrlen = standard_c_lib.strlen llstrlen = ctypes2lltype(lltype.Ptr(FUNCTYPE), cstrlen) assert lltype.typeOf(llstrlen) == lltype.Ptr(FUNCTYPE) @@ -755,7 +756,7 @@ ctypes.windll.kernel32.SetErrorMode(new_err_mode) else: underscore_on_windows = '' - strlen = rffi.llexternal('strlen', [rffi.CCHARP], rffi.SIZE_T, + strlen = rffi.llexternal('strlen', [rffi.CONST_CCHARP], rffi.SIZE_T, compilation_info=eci) os_write = rffi.llexternal(underscore_on_windows+'write', [rffi.INT, rffi.CCHARP, rffi.SIZE_T], @@ -827,7 +828,7 @@ py.test.skip("No fcntl on win32") fcntl_int = rffi.llexternal('fcntl', [rffi.INT, rffi.INT, rffi.INT], rffi.INT) - fcntl_str = rffi.llexternal('fcntl', [rffi.INT, rffi.INT, rffi.CCHARP], + fcntl_str = rffi.llexternal('fcntl', [rffi.INT, rffi.INT, rffi.CONST_CCHARP], rffi.INT) fcntl_int(12345, 1, 0) fcntl_str(12345, 3, "xxx") @@ -889,7 +890,7 @@ return one + rffi.cast(rffi.LONG, get_y()) def g(): - l = rffi.liststr2charpp(["a", "b", "c"]) + l = rffi.cast(rffi.CCHARPP, rffi.liststr2charpp(["a", "b", "c"])) try: set_z(l) return rffi.charp2str(get_z()[2]) From noreply at buildbot.pypy.org Fri Sep 13 20:10:23 2013 From: noreply at buildbot.pypy.org (amauryfa) Date: Fri, 13 Sep 2013 20:10:23 +0200 (CEST) Subject: [pypy-commit] pypy const-correctness: Fix many tests Message-ID: <20130913181023.8510D1C016D@cobra.cs.uni-duesseldorf.de> Author: Amaury Forgeot d'Arc Branch: const-correctness Changeset: r66938:abfda92315ef Date: 2013-09-13 18:17 +0200 http://bitbucket.org/pypy/pypy/changeset/abfda92315ef/ Log: Fix many tests 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 @@ -63,11 +63,11 @@ INT = rffi.INT INTP = lltype.Ptr(lltype.Array(INT, hints={'nolength':True})) -c_setupterm = rffi.llexternal('setupterm', [rffi.CCHARP, INT, INTP], INT, +c_setupterm = rffi.llexternal('setupterm', [rffi.CONST_CCHARP, INT, INTP], INT, compilation_info=eci) -c_tigetstr = rffi.llexternal('tigetstr', [rffi.CCHARP], rffi.CCHARP, +c_tigetstr = rffi.llexternal('tigetstr', [rffi.CONST_CCHARP], rffi.CCHARP, compilation_info=eci) -c_tparm = rffi.llexternal('tparm', [rffi.CCHARP, INT, INT, INT, INT, INT, +c_tparm = rffi.llexternal('tparm', [rffi.CONST_CCHARP, INT, INT, INT, INT, INT, INT, INT, INT, INT], rffi.CCHARP, compilation_info=eci) 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 @@ -80,11 +80,11 @@ compilation_info=eci, **kwargs) _sem_open = external('sem_open', - [rffi.CCHARP, rffi.INT, rffi.INT, rffi.UINT], + [rffi.CONST_CCHARP, rffi.INT, rffi.INT, rffi.UINT], SEM_T) # tread sem_close as not threadsafe for now to be able to use the __del__ _sem_close = external('sem_close', [SEM_T], rffi.INT, threadsafe=False) - _sem_unlink = external('sem_unlink', [rffi.CCHARP], rffi.INT) + _sem_unlink = external('sem_unlink', [rffi.CONST_CCHARP], rffi.INT) _sem_wait = external('sem_wait', [SEM_T], rffi.INT) _sem_trywait = external('sem_trywait', [SEM_T], rffi.INT) _sem_post = external('sem_post', [SEM_T], rffi.INT) diff --git a/rpython/jit/backend/llsupport/test/zrpy_releasegil_test.py b/rpython/jit/backend/llsupport/test/zrpy_releasegil_test.py --- a/rpython/jit/backend/llsupport/test/zrpy_releasegil_test.py +++ b/rpython/jit/backend/llsupport/test/zrpy_releasegil_test.py @@ -20,7 +20,7 @@ glob = Glob() # - c_strchr = rffi.llexternal('strchr', [rffi.CCHARP, lltype.Signed], + c_strchr = rffi.llexternal('strchr', [rffi.CONST_CCHARP, lltype.Signed], rffi.CCHARP) def func(): 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 @@ -258,7 +258,7 @@ 'int _noprof_execv(const char *path, char *argv[])', 'return execv(path, argv);') os_execv = self.llexternal('_noprof_execv', - [rffi.CONST_CCHARP, rffi.CCHARPP], + [rffi.CONST_CCHARP, rffi.CONST_CCHARPP], rffi.INT, compilation_info = eci) def execv_llimpl(path, args): @@ -394,7 +394,7 @@ @registering_str_unicode(os.utime) def register_os_utime(self, traits): UTIMBUFP = lltype.Ptr(self.UTIMBUF) - os_utime = self.llexternal('utime', [rffi.CCHARP, UTIMBUFP], rffi.INT) + os_utime = self.llexternal('utime', [rffi.CONST_CCHARP, UTIMBUFP], rffi.INT) if not _WIN32: includes = ['sys/time.h'] @@ -425,7 +425,7 @@ config = platform.configure(CConfig) TIMEVAL = config['TIMEVAL'] TIMEVAL2P = rffi.CArrayPtr(TIMEVAL) - os_utimes = self.llexternal('utimes', [rffi.CCHARP, TIMEVAL2P], + os_utimes = self.llexternal('utimes', [rffi.CONST_CCHARP, TIMEVAL2P], rffi.INT, compilation_info=CConfig._compilation_info_) def os_utime_platform(path, actime, modtime): @@ -1104,7 +1104,7 @@ config = platform.configure(CConfig) DIRENT = config['DIRENT'] DIRENTP = lltype.Ptr(DIRENT) - os_opendir = self.llexternal('opendir', [rffi.CCHARP], DIRP, + os_opendir = self.llexternal('opendir', [rffi.CONST_CCHARP], DIRP, compilation_info=compilation_info) # XXX macro=True is hack to make sure we get the correct kind of # dirent struct (which depends on defines) @@ -1206,7 +1206,7 @@ @registering_if(os, 'lchown') def register_os_lchown(self): - os_lchown = self.llexternal('lchown',[rffi.CCHARP, rffi.INT, rffi.INT], + os_lchown = self.llexternal('lchown',[rffi.CONST_CCHARP, rffi.INT, rffi.INT], rffi.INT) def os_lchown_llimpl(path, uid, gid): @@ -1233,7 +1233,7 @@ @registering_if(os, 'readlink') def register_os_readlink(self): os_readlink = self.llexternal('readlink', - [rffi.CCHARP, rffi.CCHARP, rffi.SIZE_T], + [rffi.CONST_CCHARP, rffi.CCHARP, rffi.SIZE_T], rffi.INT) # XXX SSIZE_T in POSIX.1-2001 @@ -1411,7 +1411,7 @@ @registering_str_unicode(os.rmdir) def register_os_rmdir(self, traits): os_rmdir = self.llexternal(traits.posix_function_name('rmdir'), - [traits.CCHARP], rffi.INT) + [traits.CONST_CCHARP], rffi.INT) def rmdir_llimpl(pathname): res = rffi.cast(lltype.Signed, os_rmdir(pathname)) @@ -1424,7 +1424,7 @@ @registering_str_unicode(os.chmod) def register_os_chmod(self, traits): os_chmod = self.llexternal(traits.posix_function_name('chmod'), - [traits.CCHARP, rffi.MODE_T], rffi.INT) + [traits.CONST_CCHARP, rffi.MODE_T], rffi.INT) def chmod_llimpl(path, mode): res = rffi.cast(lltype.Signed, os_chmod(path, rffi.cast(rffi.MODE_T, mode))) @@ -1455,7 +1455,7 @@ @registering_str_unicode(os.rename) def register_os_rename(self, traits): os_rename = self.llexternal(traits.posix_function_name('rename'), - [traits.CCHARP, traits.CCHARP], rffi.INT) + [traits.CONST_CCHARP, traits.CONST_CCHARP], rffi.INT) def rename_llimpl(oldpath, newpath): res = rffi.cast(lltype.Signed, os_rename(oldpath, newpath)) @@ -1477,7 +1477,7 @@ @registering_str_unicode(getattr(os, 'mkfifo', None)) def register_os_mkfifo(self, traits): os_mkfifo = self.llexternal(traits.posix_function_name('mkfifo'), - [traits.CCHARP, rffi.MODE_T], rffi.INT) + [traits.CONST_CCHARP, rffi.MODE_T], rffi.INT) def mkfifo_llimpl(path, mode): res = rffi.cast(lltype.Signed, os_mkfifo(path, mode)) @@ -1490,7 +1490,7 @@ @registering_str_unicode(getattr(os, 'mknod', None)) def register_os_mknod(self, traits): os_mknod = self.llexternal(traits.posix_function_name('mknod'), - [traits.CCHARP, rffi.MODE_T, rffi.INT], + [traits.CONST_CCHARP, rffi.MODE_T, rffi.INT], rffi.INT) # xxx: actually ^^^ dev_t def mknod_llimpl(path, mode, dev): @@ -1540,7 +1540,7 @@ @registering_if(os, 'link') def register_os_link(self): - os_link = self.llexternal('link', [rffi.CCHARP, rffi.CCHARP], + os_link = self.llexternal('link', [rffi.CONST_CCHARP, rffi.CONST_CCHARP], rffi.INT) def link_llimpl(oldpath, newpath): @@ -1553,7 +1553,7 @@ @registering_if(os, 'symlink') def register_os_symlink(self): - os_symlink = self.llexternal('symlink', [rffi.CCHARP, rffi.CCHARP], + os_symlink = self.llexternal('symlink', [rffi.CONST_CCHARP, rffi.CONST_CCHARP], rffi.INT) def symlink_llimpl(oldpath, newpath): 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 @@ -31,12 +31,12 @@ sandboxsafe=True) ll_write_not_sandboxed = rffi.llexternal('write', - [rffi.INT, rffi.CCHARP, rffi.SIZE_T], + [rffi.INT, rffi.CONST_CCHARP, rffi.SIZE_T], rffi.SIZE_T, sandboxsafe=True) - at signature(types.int(), types.ptr(rffi.CCHARP.TO), types.int(), returns=types.none()) + at signature(types.int(), types.ptr(rffi.CONST_CCHARP.TO), types.int(), returns=types.none()) def writeall_not_sandboxed(fd, buf, length): while length > 0: size = rffi.cast(rffi.SIZE_T, length) From noreply at buildbot.pypy.org Fri Sep 13 21:55:11 2013 From: noreply at buildbot.pypy.org (amauryfa) Date: Fri, 13 Sep 2013 21:55:11 +0200 (CEST) Subject: [pypy-commit] pypy const-correctness: Fix Message-ID: <20130913195511.8E3C61C0E26@cobra.cs.uni-duesseldorf.de> Author: Amaury Forgeot d'Arc Branch: const-correctness Changeset: r66940:b3d07d1dab74 Date: 2013-09-13 21:52 +0200 http://bitbucket.org/pypy/pypy/changeset/b3d07d1dab74/ Log: Fix diff --git a/rpython/rtyper/lltypesystem/lltype.py b/rpython/rtyper/lltypesystem/lltype.py --- a/rpython/rtyper/lltypesystem/lltype.py +++ b/rpython/rtyper/lltypesystem/lltype.py @@ -128,7 +128,7 @@ object.__setattr__(self, attr, nvalue) def _enforce(self, value): - if typeOf(value) != self: + if not isConvertibleFrom(self, typeOf(value)): raise TypeError return value From noreply at buildbot.pypy.org Fri Sep 13 21:55:12 2013 From: noreply at buildbot.pypy.org (amauryfa) Date: Fri, 13 Sep 2013 21:55:12 +0200 (CEST) Subject: [pypy-commit] pypy const-correctness: Fix again. Message-ID: <20130913195512.B01591C12F0@cobra.cs.uni-duesseldorf.de> Author: Amaury Forgeot d'Arc Branch: const-correctness Changeset: r66941:60712d9dbfd3 Date: 2013-09-13 21:54 +0200 http://bitbucket.org/pypy/pypy/changeset/60712d9dbfd3/ Log: Fix again. Should find a better name for this function. diff --git a/rpython/rtyper/lltypesystem/lltype.py b/rpython/rtyper/lltypesystem/lltype.py --- a/rpython/rtyper/lltypesystem/lltype.py +++ b/rpython/rtyper/lltypesystem/lltype.py @@ -1762,7 +1762,7 @@ return v def setitem(self, index, value): - assert typeOf(value) == self._TYPE.OF + assert isConvertibleFrom(self._TYPE.OF, typeOf(value)) self.items[index] = value assert not '__dict__' in dir(_array) From noreply at buildbot.pypy.org Sat Sep 14 03:47:55 2013 From: noreply at buildbot.pypy.org (wlav) Date: Sat, 14 Sep 2013 03:47:55 +0200 (CEST) Subject: [pypy-commit] pypy reflex-support: fixed typo in comment Message-ID: <20130914014755.B6AB81C016D@cobra.cs.uni-duesseldorf.de> Author: Wim Lavrijsen Branch: reflex-support Changeset: r66942:7551188e6c6d Date: 2013-09-12 17:59 -0700 http://bitbucket.org/pypy/pypy/changeset/7551188e6c6d/ Log: fixed typo in comment 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 @@ -277,7 +277,7 @@ if (ti.Property() & G__BIT_ISENUM) return cppstring_to_cstring("unsigned int"); - // actual typedef resolution; add back array declartion portion, if needed + // actual typedef resolution; add back array declaration portion, if needed std::string rt = ti.TrueName(); // builtin STL types have fake typedefs :/ From noreply at buildbot.pypy.org Sat Sep 14 03:47:56 2013 From: noreply at buildbot.pypy.org (wlav) Date: Sat, 14 Sep 2013 03:47:56 +0200 (CEST) Subject: [pypy-commit] pypy reflex-support: test that global methods can be installed as member functions Message-ID: <20130914014756.DE9841C016D@cobra.cs.uni-duesseldorf.de> Author: Wim Lavrijsen Branch: reflex-support Changeset: r66943:70107f8d73a6 Date: 2013-09-13 11:25 -0700 http://bitbucket.org/pypy/pypy/changeset/70107f8d73a6/ Log: test that global methods can be installed as member functions diff --git a/pypy/module/cppyy/test/example01.cxx b/pypy/module/cppyy/test/example01.cxx --- a/pypy/module/cppyy/test/example01.cxx +++ b/pypy/module/cppyy/test/example01.cxx @@ -156,6 +156,10 @@ return ::globalAddOneToInt(a); } +int installableAddOneToInt(example01& e, int a) { + return e.staticAddOneToInt(a); +} + int ns_example01::gMyGlobalInt = 99; diff --git a/pypy/module/cppyy/test/example01.h b/pypy/module/cppyy/test/example01.h --- a/pypy/module/cppyy/test/example01.h +++ b/pypy/module/cppyy/test/example01.h @@ -67,6 +67,8 @@ extern int gMyGlobalInt; } +int installableAddOneToInt(example01&, int a); + #define itypeValue(itype, tname) \ itype tname##Value(itype arg0, int argn=0, itype arg1=1, itype arg2=2) diff --git a/pypy/module/cppyy/test/example01.xml b/pypy/module/cppyy/test/example01.xml --- a/pypy/module/cppyy/test/example01.xml +++ b/pypy/module/cppyy/test/example01.xml @@ -8,6 +8,7 @@ + diff --git a/pypy/module/cppyy/test/example01_LinkDef.h b/pypy/module/cppyy/test/example01_LinkDef.h --- a/pypy/module/cppyy/test/example01_LinkDef.h +++ b/pypy/module/cppyy/test/example01_LinkDef.h @@ -12,6 +12,7 @@ #pragma link C++ class z_; #pragma link C++ function globalAddOneToInt(int); +#pragma link C++ function installableAddOneToInt(example01&, int); #pragma link C++ namespace ns_example01; #pragma link C++ function ns_example01::globalAddOneToInt(int); 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 @@ -327,6 +327,17 @@ e = cppyy.gbl.example01(2) assert 5 == meth(e, 3) + def test01_installable_function(self): + """Test installing and calling global C++ function as python method""" + + import cppyy + + cppyy.gbl.example01.fresh = cppyy.gbl.installableAddOneToInt + + e = cppyy.gbl.example01(0) + assert 2 == e.fresh(1) + assert 3 == e.fresh(2) + class AppTestPYTHONIFY_UI: spaceconfig = dict(usemodules=['cppyy', '_rawffi', '_ffi', 'itertools']) From noreply at buildbot.pypy.org Sat Sep 14 03:47:58 2013 From: noreply at buildbot.pypy.org (wlav) Date: Sat, 14 Sep 2013 03:47:58 +0200 (CEST) Subject: [pypy-commit] pypy reflex-support: TF1 callbacks and associated tests Message-ID: <20130914014758.177AA1C016D@cobra.cs.uni-duesseldorf.de> Author: Wim Lavrijsen Branch: reflex-support Changeset: r66944:d2f110893a4b Date: 2013-09-13 15:39 -0700 http://bitbucket.org/pypy/pypy/changeset/d2f110893a4b/ Log: TF1 callbacks 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 @@ -99,6 +99,55 @@ return w_1 return obj.space.call_method(w_1, m2) +### TF1 ---------------------------------------------------------------------- +tfn_pyfuncs = {} + +_tfn_install = rffi.llexternal( + "cppyy_tfn_install", + [rffi.CCHARP, rffi.INT], rffi.LONG, + threadsafe=False, + compilation_info=eci) + + at unwrap_spec(args_w='args_w') +def tf1_tf1(space, w_self, args_w): + """Pythonized version of TF1 constructor: + takes functions and callable objects, and allows a callback into them.""" + + from pypy.module.cppyy import interp_cppyy + tf1_class = interp_cppyy.scope_byname(space, "TF1") + + # expected signature: + # 1. (char* name, pyfunc, double xmin, double xmax, int npar = 0) + argc = len(args_w) + + try: + # Note: argcount is +1 for the class (== w_self) + if argc < 5 or 6 < argc: + raise TypeError("wrong number of arguments") + + # second argument must be a name + funcname = space.str_w(args_w[1]) + + # last (optional) argument is number of parameters + npar = 0 + if argc == 6: npar = space.int_w(args_w[5]) + + # third argument must be a callable python object + pyfunc = args_w[2] + if not space.is_true(space.callable(pyfunc)): + raise TypeError("2nd argument is not a valid python callable") + + fid = _tfn_install(funcname, npar) + tfn_pyfuncs[fid] = pyfunc + newargs_w = (args_w[1], space.wrap(fid), args_w[3], args_w[4], space.wrap(npar)) + except (OperationError, TypeError, IndexError): + newargs_w = args_w[1:] # drop class + pass + + # return control back to the original, unpythonized overload + ol = tf1_class.get_overload("TF1") + return ol.call(None, newargs_w) + ### TTree -------------------------------------------------------------------- _ttree_Branch = rffi.llexternal( "cppyy_ttree_Branch", @@ -293,6 +342,9 @@ allfuncs = [ + ### TF1 + tf1_tf1, + ### TTree ttree_Branch, ttree_iter, ttree_getattr, ] @@ -311,6 +363,9 @@ _method_alias(space, w_pycppclass, "append", "Add") _method_alias(space, w_pycppclass, "__len__", "GetSize") + elif name == "TF1": + space.setattr(w_pycppclass, space.wrap("__new__"), _pythonizations["tf1_tf1"]) + elif name == "TFile": _method_alias(space, w_pycppclass, "__getattr__", "Get") @@ -347,3 +402,26 @@ if obj is not None: memory_regulator.unregister(obj) obj._rawobject = C_NULL_OBJECT + +# TFn callback (as above: needs better solution, but this is for CINT only) +# TODO: it actually can fail ... + at cpython_api([rffi.LONG, rffi.INT, rffi.DOUBLEP, rffi.DOUBLEP], rffi.DOUBLE, error=CANNOT_FAIL) +def cppyy_tfn_callback(space, idx, npar, a0, a1): + pyfunc = tfn_pyfuncs[idx] + + from pypy.module._rawffi.interp_rawffi import unpack_simple_shape + from pypy.module._rawffi.array import W_Array, W_ArrayInstance + arr = space.interp_w(W_Array, unpack_simple_shape(space, space.wrap('d'))) + address = rffi.cast(rffi.ULONG, a0) + arg0 = arr.fromaddress(space, address, 4) + try: + if npar != 0: + address = rffi.cast(rffi.ULONG, a1) + arg1 = arr.fromaddress(space, address, npar) + result = space.call_function(pyfunc, arg0, arg1) + else: + result = space.call_function(pyfunc, arg0) + except Exception: + # TODO: error handling here .. + return -1. + return space.float_w(result) 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 @@ -372,7 +372,12 @@ try: obj = get_rawbuffer(space, w_obj) except TypeError: - obj = rffi.cast(rffi.VOIDP, get_rawobject(space, w_obj)) + try: + # TODO: accept a 'capsule' rather than naked int + # (do accept int(0), though) + obj = rffi.cast(rffi.VOIDP, space.int_w(w_obj)) + except Exception: + obj = rffi.cast(rffi.VOIDP, get_rawobject(space, w_obj)) return obj def convert_argument(self, space, w_obj, address, call_local): diff --git a/pypy/module/cppyy/include/cintcwrapper.h b/pypy/module/cppyy/include/cintcwrapper.h --- a/pypy/module/cppyy/include/cintcwrapper.h +++ b/pypy/module/cppyy/include/cintcwrapper.h @@ -11,6 +11,8 @@ void* cppyy_load_dictionary(const char* lib_name); /* pythonization helpers */ + long cppyy_tfn_install(const char* funcname, int npar); + cppyy_object_t cppyy_ttree_Branch( void* vtree, const char* branchname, const char* classname, void* addobj, int bufsize, int splitlevel); 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 @@ -62,6 +62,9 @@ // memory regulation (cppyy_recursive_remove is generated a la cpyext capi calls) extern "C" void cppyy_recursive_remove(void*); +// TFN callback helper (generated a la cpyext capi calls) +extern "C" double cppyy_tfn_callback(long, int, double*, double*); + class Cppyy_MemoryRegulator : public TObject { public: virtual void RecursiveRemove(TObject* object) { @@ -987,6 +990,61 @@ /* pythonization helpers -------------------------------------------------- */ +static std::map > s_tagnum2fid; + +static int TFNPyCallback(G__value* res, G__CONST char*, struct G__param* libp, int hash) { + // This is a generic CINT-installable TFN (with N=1,2,3) callback (used to factor + // out some common code), to allow TFN to call back into python. + + std::pair fid_and_npar = s_tagnum2fid[G__value_get_tagnum(res)]; + + // callback (defined in cint_capi.py) + double d = cppyy_tfn_callback(fid_and_npar.first, fid_and_npar.second, + (double*)G__int(libp->para[0]), fid_and_npar.second ? (double*)G__int(libp->para[1]) : NULL); + + // translate result (TODO: error checking) + G__letdouble( res, 100, d ); + return ( 1 || hash || res || libp ); +} + +long cppyy_tfn_install(const char* funcname, int npar) { + // make a new function placeholder known to CINT + static Long_t s_fid = (Long_t)cppyy_tfn_install; + ++s_fid; + + const char* signature = "D - - 0 - - D - - 0 - -"; + + // create a return type (typically masked/wrapped by a TPyReturn) for the method + G__linked_taginfo pti; + pti.tagnum = -1; + pti.tagtype = 'c'; + std::string tagname("::py_"); // used as a buffer + tagname += funcname; + pti.tagname = tagname.c_str(); + int tagnum = G__get_linked_tagnum(&pti); // creates entry for new names + + // for free functions, add to global scope and add lookup through tp2f + // setup a connection between the pointer and the name + Long_t hash = 0, len = 0; + G__hash(funcname, hash, len); + G__lastifuncposition(); + G__memfunc_setup(funcname, hash, (G__InterfaceMethod)&TFNPyCallback, + tagnum, tagnum, tagnum, 0, 2, 0, 1, 0, signature, + (char*)0, (void*)s_fid, 0); + G__resetifuncposition(); + + // setup a name in the global namespace (does not result in calls, so the signature + // does not matter; but it makes subsequent GetMethod() calls work) + G__MethodInfo meth = G__ClassInfo().AddMethod( + funcname, funcname, signature, 1, 0, (void*)&TFNPyCallback); + + // store mapping so that the callback can find it + s_tagnum2fid[tagnum] = std::make_pair(s_fid, npar); + + // hard to check result ... assume ok + return s_fid; +} + cppyy_object_t cppyy_ttree_Branch(void* vtree, const char* branchname, const char* classname, void* addobj, int bufsize, int splitlevel) { // this little song-and-dance is to by-pass the handwritten Branch methods 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 @@ -430,6 +430,84 @@ hello.AddText( 'Hello, World!' ) +class AppTestCINTFUNCTION: + spaceconfig = dict(usemodules=['cppyy', '_rawffi', '_ffi', 'itertools']) + + # test the function callbacks; this does not work with Reflex, as it can + # not generate functions on the fly (it might with cffi?) + + def test01_global_function_callback(self): + """Test callback of a python global function""" + + import cppyy + TF1 = cppyy.gbl.TF1 + + def identity(x): + return x[0] + + f = TF1("pyf1", identity, -1., 1., 0) + + assert f.Eval(0.5) == 0.5 + assert f.Eval(-10.) == -10. + assert f.Eval(1.0) == 1.0 + + # check proper propagation of default value + f = TF1("pyf1d", identity, -1., 1.) + + assert f.Eval(0.5) == 0.5 + + def test02_callable_object_callback(self): + """Test callback of a python callable object""" + + import cppyy + TF1 = cppyy.gbl.TF1 + + class Linear: + def __call__(self, x, par): + return par[0] + x[0]*par[1] + + f = TF1("pyf2", Linear(), -1., 1., 2) + f.SetParameters(5., 2.) + + assert f.Eval(-0.1) == 4.8 + assert f.Eval(1.3) == 7.6 + + def test03_fit_with_python_gaussian(self): + """Test fitting with a python global function""" + + # note: this function is dread-fully slow when running testing un-translated + + import cppyy, math + TF1, TH1F = cppyy.gbl.TF1, cppyy.gbl.TH1F + + def pygaus(x, par): + arg1 = 0 + scale1 =0 + ddx = 0.01 + + if (par[2] != 0.0): + arg1 = (x[0]-par[1])/par[2] + scale1 = (ddx*0.39894228)/par[2] + h1 = par[0]/(1+par[3]) + + gauss = h1*scale1*math.exp(-0.5*arg1*arg1) + else: + gauss = 0. + return gauss + + f = TF1("pygaus", pygaus, -4, 4, 4) + f.SetParameters(600, 0.43, 0.35, 600) + + h = TH1F("h", "test", 100, -4, 4) + h.FillRandom("gaus", 200000) + h.Fit(f, "0Q") + + assert f.GetNDF() == 96 + result = f.GetParameters() + assert round(result[1] - 0., 1) == 0 # mean + assert round(result[2] - 1., 1) == 0 # s.d. + + class AppTestSURPLUS: spaceconfig = dict(usemodules=['cppyy', '_rawffi', '_ffi', 'itertools']) From noreply at buildbot.pypy.org Sat Sep 14 03:47:59 2013 From: noreply at buildbot.pypy.org (wlav) Date: Sat, 14 Sep 2013 03:47:59 +0200 (CEST) Subject: [pypy-commit] pypy reflex-support: fix rtyper issues Message-ID: <20130914014759.3C8091C016D@cobra.cs.uni-duesseldorf.de> Author: Wim Lavrijsen Branch: reflex-support Changeset: r66945:f04a6bd8cb77 Date: 2013-09-13 18:46 -0700 http://bitbucket.org/pypy/pypy/changeset/f04a6bd8cb77/ Log: fix rtyper issues 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 @@ -139,7 +139,7 @@ fid = _tfn_install(funcname, npar) tfn_pyfuncs[fid] = pyfunc - newargs_w = (args_w[1], space.wrap(fid), args_w[3], args_w[4], space.wrap(npar)) + newargs_w = [args_w[1], space.wrap(fid), args_w[3], args_w[4], space.wrap(npar)] except (OperationError, TypeError, IndexError): newargs_w = args_w[1:] # drop class pass @@ -408,6 +408,7 @@ @cpython_api([rffi.LONG, rffi.INT, rffi.DOUBLEP, rffi.DOUBLEP], rffi.DOUBLE, error=CANNOT_FAIL) def cppyy_tfn_callback(space, idx, npar, a0, a1): pyfunc = tfn_pyfuncs[idx] + npar = int(npar) from pypy.module._rawffi.interp_rawffi import unpack_simple_shape from pypy.module._rawffi.array import W_Array, W_ArrayInstance From noreply at buildbot.pypy.org Sat Sep 14 09:54:43 2013 From: noreply at buildbot.pypy.org (arigo) Date: Sat, 14 Sep 2013 09:54:43 +0200 (CEST) Subject: [pypy-commit] cffi default: Two tests from the mailing list, and fixes: bogus "const" detection, Message-ID: <20130914075443.DB1151C0842@cobra.cs.uni-duesseldorf.de> Author: Armin Rigo Branch: Changeset: r1348:e2728981fbaa Date: 2013-09-14 09:54 +0200 http://bitbucket.org/cffi/cffi/changeset/e2728981fbaa/ Log: Two tests from the mailing list, and fixes: bogus "const" detection, and global array variables should never be "const". diff --git a/cffi/cparser.py b/cffi/cparser.py --- a/cffi/cparser.py +++ b/cffi/cparser.py @@ -217,7 +217,7 @@ # if decl.name: tp = self._get_type(node, partial_length_ok=True) - if self._is_constant_declaration(node): + if self._is_constant_globalvar(node): self._declare('constant ' + decl.name, tp) else: self._declare('variable ' + decl.name, tp) @@ -372,14 +372,11 @@ result = self._get_type(typenode.type) return model.RawFunctionType(tuple(args), result, ellipsis) - def _is_constant_declaration(self, typenode, const=False): - if isinstance(typenode, pycparser.c_ast.ArrayDecl): - return self._is_constant_declaration(typenode.type) + def _is_constant_globalvar(self, typenode): if isinstance(typenode, pycparser.c_ast.PtrDecl): - const = 'const' in typenode.quals - return self._is_constant_declaration(typenode.type, const) + return 'const' in typenode.quals if isinstance(typenode, pycparser.c_ast.TypeDecl): - return const or 'const' in typenode.quals + return 'const' in typenode.quals return False def _get_struct_union_enum_type(self, kind, type, name=None, nested=False): diff --git a/cffi/model.py b/cffi/model.py --- a/cffi/model.py +++ b/cffi/model.py @@ -192,10 +192,6 @@ _base_pattern = " const *&" _base_pattern_array = "(const *&)" - def build_backend_type(self, ffi, finishlist): - BPtr = PointerType(self.totype).get_cached_btype(ffi, finishlist) - return BPtr - const_voidp_type = ConstPointerType(void_type) diff --git a/testing/test_parsing.py b/testing/test_parsing.py --- a/testing/test_parsing.py +++ b/testing/test_parsing.py @@ -255,3 +255,27 @@ py.test.skip("Only for Windows") ffi = FFI() ffi.cdef("void f(WPARAM);") + +def test__is_constant_globalvar(): + from cffi.cparser import Parser, _get_parser + for input, expected_output in [ + ("int a;", False), + ("const int a;", True), + ("int *a;", False), + ("const int *a;", False), + ("int const *a;", False), + ("int *const a;", True), + ("int a[5];", False), + ("const int a[5];", False), + ("int *a[5];", False), + ("const int *a[5];", False), + ("int const *a[5];", False), + ("int *const a[5];", False), + ("int a[5][6];", False), + ("const int a[5][6];", False), + ]: + p = Parser() + ast = _get_parser().parse(input) + decl = ast.children()[0][1] + node = decl.type + assert p._is_constant_globalvar(node) == expected_output diff --git a/testing/test_verify.py b/testing/test_verify.py --- a/testing/test_verify.py +++ b/testing/test_verify.py @@ -1644,3 +1644,16 @@ m = lib.foo(s[0]) assert m == -1234 assert repr(ffi.typeof(lib.foo)) == "" + +def test_bug_const_char_ptr_array_1(): + ffi = FFI() + ffi.cdef("""const char *a[...];""") + lib = ffi.verify("""const char *a[5];""") + assert repr(ffi.typeof(lib.a)) == "" + +def test_bug_const_char_ptr_array_2(): + from cffi import FFI # ignore warnings + ffi = FFI() + ffi.cdef("""const int a[];""") + lib = ffi.verify("""const int a[5];""") + assert repr(ffi.typeof(lib.a)) == "" From noreply at buildbot.pypy.org Sat Sep 14 16:28:18 2013 From: noreply at buildbot.pypy.org (arigo) Date: Sat, 14 Sep 2013 16:28:18 +0200 (CEST) Subject: [pypy-commit] extradoc extradoc: Small change (Thanks Laura) Message-ID: <20130914142818.AD2DD1C0842@cobra.cs.uni-duesseldorf.de> Author: Armin Rigo Branch: extradoc Changeset: r5059:cfabe6782afc Date: 2013-09-14 16:26 +0200 http://bitbucket.org/pypy/extradoc/changeset/cfabe6782afc/ Log: Small change (Thanks Laura) diff --git a/talk/pycon2014/abstract.rst b/talk/pycon2014/abstract.rst --- a/talk/pycon2014/abstract.rst +++ b/talk/pycon2014/abstract.rst @@ -49,8 +49,9 @@ parallelism.) Depending on the status of pypy-stm at the time of the presentation, I -will give demos of this, explaining in detail what people can expect to -have to change (very little), and how it performs on real applications. +will give demos of this, explaining in detail which kinds of programs +are amenable to parallelism and which are not; and for the ones that +are, how pypy-stm performs. I will then give a comparison with the alternative approaches: independent processes; the stdlib 'multiprocessing' package; or custom From noreply at buildbot.pypy.org Sat Sep 14 19:40:20 2013 From: noreply at buildbot.pypy.org (vext01) Date: Sat, 14 Sep 2013 19:40:20 +0200 (CEST) Subject: [pypy-commit] jitviewer argparse-collect: Revise the README now that argparse interface is implemented. Message-ID: <20130914174020.7AF291C0162@cobra.cs.uni-duesseldorf.de> Author: Edd Barrett Branch: argparse-collect Changeset: r249:6b6a853e104f Date: 2013-09-12 20:56 +0100 http://bitbucket.org/pypy/jitviewer/changeset/6b6a853e104f/ Log: Revise the README now that argparse interface is implemented. diff --git a/README b/README --- a/README +++ b/README @@ -23,10 +23,6 @@ source code is (roughly) the same version as the binary pypy that produced the log file. -Finally, run it: +For usage information, invoke jitviewer.py with --help. - jitviewer.py log.pypylog - -where log.pypylog is a logfile generated by -PYPYLOG=jit-log-opt,jit-backend:log.pypylog pypy . -An example log file comes with a checkout. +An example log file is shipped with the jitviewer source code. From noreply at buildbot.pypy.org Sat Sep 14 19:40:21 2013 From: noreply at buildbot.pypy.org (arigo) Date: Sat, 14 Sep 2013 19:40:21 +0200 (CEST) Subject: [pypy-commit] jitviewer default: Merged in vext01/jitviewer/argparse-collect (pull request #6) Message-ID: <20130914174021.9B5D21C0842@cobra.cs.uni-duesseldorf.de> Author: Armin Rigo Branch: Changeset: r250:f2064f256d8a Date: 2013-09-14 19:40 +0200 http://bitbucket.org/pypy/jitviewer/changeset/f2064f256d8a/ Log: Merged in vext01/jitviewer/argparse-collect (pull request #6) Revise README in light of recent changes to jitviewer. diff --git a/README b/README --- a/README +++ b/README @@ -23,10 +23,6 @@ source code is (roughly) the same version as the binary pypy that produced the log file. -Finally, run it: +For usage information, invoke jitviewer.py with --help. - jitviewer.py log.pypylog - -where log.pypylog is a logfile generated by -PYPYLOG=jit-log-opt,jit-backend:log.pypylog pypy . -An example log file comes with a checkout. +An example log file is shipped with the jitviewer source code. From noreply at buildbot.pypy.org Sun Sep 15 00:28:10 2013 From: noreply at buildbot.pypy.org (mattip) Date: Sun, 15 Sep 2013 00:28:10 +0200 (CEST) Subject: [pypy-commit] pypy safe-win-mmap: mimic posix safe/unsafe versions of external functions Message-ID: <20130914222810.4DD901C0162@cobra.cs.uni-duesseldorf.de> Author: mattip Branch: safe-win-mmap Changeset: r66946:fe5c92d26b23 Date: 2013-09-14 23:07 +0300 http://bitbucket.org/pypy/pypy/changeset/fe5c92d26b23/ Log: mimic posix safe/unsafe versions of external functions diff --git a/rpython/rlib/rmmap.py b/rpython/rlib/rmmap.py --- a/rpython/rlib/rmmap.py +++ b/rpython/rlib/rmmap.py @@ -118,10 +118,16 @@ return unsafe, safe def winexternal(name, args, result, **kwargs): - return rffi.llexternal(name, args, result, + unsafe = rffi.llexternal(name, args, result, compilation_info=CConfig._compilation_info_, calling_conv='win', **kwargs) + safe = rffi.llexternal(name, args, result, + compilation_info=CConfig._compilation_info_, + calling_conv='win', + sandboxsafe=True, threadsafe=False, + **kwargs) + return unsafe, safe PTR = rffi.CCHARP @@ -188,32 +194,34 @@ SYSTEM_INFO = config['SYSTEM_INFO'] SYSTEM_INFO_P = lltype.Ptr(SYSTEM_INFO) - GetSystemInfo = winexternal('GetSystemInfo', [SYSTEM_INFO_P], lltype.Void) - GetFileSize = winexternal('GetFileSize', [HANDLE, LPDWORD], DWORD) - GetCurrentProcess = winexternal('GetCurrentProcess', [], HANDLE) - DuplicateHandle = winexternal('DuplicateHandle', [HANDLE, HANDLE, HANDLE, LPHANDLE, DWORD, BOOL, DWORD], BOOL) - CreateFileMapping = winexternal('CreateFileMappingA', [HANDLE, rwin32.LPSECURITY_ATTRIBUTES, DWORD, DWORD, DWORD, LPCSTR], HANDLE) - MapViewOfFile = winexternal('MapViewOfFile', [HANDLE, DWORD, DWORD, DWORD, SIZE_T], LPCSTR)##!!LPVOID) - UnmapViewOfFile = winexternal('UnmapViewOfFile', [LPCSTR], BOOL, - threadsafe=False) - FlushViewOfFile = winexternal('FlushViewOfFile', [LPCSTR, SIZE_T], BOOL) - SetFilePointer = winexternal('SetFilePointer', [HANDLE, LONG, PLONG, DWORD], DWORD) - SetEndOfFile = winexternal('SetEndOfFile', [HANDLE], BOOL) - VirtualAlloc = winexternal('VirtualAlloc', + GetSystemInfo, _ = winexternal('GetSystemInfo', [SYSTEM_INFO_P], lltype.Void) + GetFileSize, _ = winexternal('GetFileSize', [HANDLE, LPDWORD], DWORD) + GetCurrentProcess, _ = winexternal('GetCurrentProcess', [], HANDLE) + DuplicateHandle, _ = winexternal('DuplicateHandle', [HANDLE, HANDLE, HANDLE, LPHANDLE, DWORD, BOOL, DWORD], BOOL) + CreateFileMapping, _ = winexternal('CreateFileMappingA', [HANDLE, rwin32.LPSECURITY_ATTRIBUTES, DWORD, DWORD, DWORD, LPCSTR], HANDLE) + MapViewOfFile, _ = winexternal('MapViewOfFile', [HANDLE, DWORD, DWORD, DWORD, SIZE_T], LPCSTR)##!!LPVOID) + _, UnmapViewOfFile = winexternal('UnmapViewOfFile', [LPCSTR], BOOL) + FlushViewOfFile, _ = winexternal('FlushViewOfFile', [LPCSTR, SIZE_T], BOOL) + SetFilePointer, _ = winexternal('SetFilePointer', [HANDLE, LONG, PLONG, DWORD], DWORD) + SetEndOfFile, _ = winexternal('SetEndOfFile', [HANDLE], BOOL) + VirtualAlloc, VirtualAlloc_safe = winexternal('VirtualAlloc', [rffi.VOIDP, rffi.SIZE_T, DWORD, DWORD], rffi.VOIDP) # VirtualProtect is used in llarena and should not release the GIL - _VirtualProtect = winexternal('VirtualProtect', + _VirtualProtect, _ = winexternal('VirtualProtect', [rffi.VOIDP, rffi.SIZE_T, DWORD, LPDWORD], BOOL, _nowrapper=True) + _, VirtualProtect_safe = winexternal('VirtualProtect', + [rffi.VOIDP, rffi.SIZE_T, DWORD, LPDWORD], + BOOL) def VirtualProtect(addr, size, mode, oldmode_ptr): return _VirtualProtect(addr, rffi.cast(rffi.SIZE_T, size), rffi.cast(DWORD, mode), oldmode_ptr) VirtualProtect._annspecialcase_ = 'specialize:ll' - VirtualFree = winexternal('VirtualFree', + VirtualFree, VirtualFree_safe = winexternal('VirtualFree', [rffi.VOIDP, rffi.SIZE_T, DWORD], BOOL) def _get_page_size(): @@ -846,18 +854,18 @@ case of a sandboxed process """ null = lltype.nullptr(rffi.VOIDP.TO) - res = VirtualAlloc(null, map_size, MEM_COMMIT | MEM_RESERVE, + res = VirtualAlloc_safe(null, map_size, MEM_COMMIT | MEM_RESERVE, PAGE_EXECUTE_READWRITE) if not res: raise MemoryError arg = lltype.malloc(LPDWORD.TO, 1, zero=True, flavor='raw') - VirtualProtect(res, map_size, PAGE_EXECUTE_READWRITE, arg) + VirtualProtect_safe(res, map_size, PAGE_EXECUTE_READWRITE, arg) lltype.free(arg, flavor='raw') # ignore errors, just try return res alloc._annenforceargs_ = (int,) def free(ptr, map_size): - VirtualFree(ptr, 0, MEM_RELEASE) + VirtualFree_safe(ptr, 0, MEM_RELEASE) # register_external here? From noreply at buildbot.pypy.org Sun Sep 15 00:28:11 2013 From: noreply at buildbot.pypy.org (mattip) Date: Sun, 15 Sep 2013 00:28:11 +0200 (CEST) Subject: [pypy-commit] pypy safe-win-mmap: pass tests Message-ID: <20130914222811.8F72A1C0162@cobra.cs.uni-duesseldorf.de> Author: mattip Branch: safe-win-mmap Changeset: r66947:8a67fc795ed9 Date: 2013-09-14 23:11 +0300 http://bitbucket.org/pypy/pypy/changeset/8a67fc795ed9/ Log: pass tests diff --git a/rpython/rlib/rmmap.py b/rpython/rlib/rmmap.py --- a/rpython/rlib/rmmap.py +++ b/rpython/rlib/rmmap.py @@ -583,6 +583,7 @@ def getitem(self, index): # simplified version, for rpython + self.check_valid() if index < 0: index += self.size return self.data[index] diff --git a/rpython/rtyper/tool/rffi_platform.py b/rpython/rtyper/tool/rffi_platform.py --- a/rpython/rtyper/tool/rffi_platform.py +++ b/rpython/rtyper/tool/rffi_platform.py @@ -844,6 +844,10 @@ library_dir = '' libraries = ['gc64_dll'] includes = ['gc.h'] + # since config_external_library does not use a platform kwarg, + # somehow using a platform kw arg make the merge fail in + # config_external_library + platform = None else: library_dir = '' libraries = ['gc', 'dl'] From noreply at buildbot.pypy.org Sun Sep 15 00:36:04 2013 From: noreply at buildbot.pypy.org (pjenvey) Date: Sun, 15 Sep 2013 00:36:04 +0200 (CEST) Subject: [pypy-commit] pypy py3k: issue #1601: fix wide build detection, we_are_translated doesn't work at module Message-ID: <20130914223604.6B9891C016D@cobra.cs.uni-duesseldorf.de> Author: Philip Jenvey Branch: py3k Changeset: r66948:4e8538d98f8d Date: 2013-09-14 15:34 -0700 http://bitbucket.org/pypy/pypy/changeset/4e8538d98f8d/ Log: issue #1601: fix wide build detection, we_are_translated doesn't work at module level! 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 @@ -12,13 +12,6 @@ from rpython.rtyper.lltypesystem import lltype, rffi from rpython.translator.tool.cbuild import ExternalCompilationInfo -if we_are_translated(): - UNICHAR_SIZE = rffi.sizeof(lltype.UniChar) -else: - UNICHAR_SIZE = 2 if sys.maxunicode == 0xFFFF else 4 -MERGE_SURROGATES = UNICHAR_SIZE == 2 and rffi.sizeof(rffi.WCHAR_T) == 4 - - cwd = py.path.local(__file__).dirpath() eci = ExternalCompilationInfo( includes=[cwd.join('locale.h')], @@ -114,7 +107,10 @@ def unicode2rawwcharp(u): """unicode -> raw wchar_t*""" - size = _unicode2rawwcharp_loop(u, None) if MERGE_SURROGATES else len(u) + if _should_merge_surrogates(): + size = _unicode2rawwcharp_loop(u, None) + else: + size = len(u) array = lltype.malloc(RAW_WCHARP.TO, size + 1, flavor='raw') array[size] = rffi.cast(rffi.WCHAR_T, u'\x00') _unicode2rawwcharp_loop(u, array) @@ -127,7 +123,7 @@ count = i = 0 while i < ulen: oc = ord(u[i]) - if (MERGE_SURROGATES and + if (_should_merge_surrogates() and 0xD800 <= oc <= 0xDBFF and i + 1 < ulen and 0xDC00 <= ord(u[i + 1]) <= 0xDFFF): if write: @@ -152,3 +148,11 @@ i += 1 return assert_str0(b.build()) rawwcharp2unicoden._annenforceargs_ = [None, int] + + +def _should_merge_surrogates(): + if we_are_translated(): + unichar_size = rffi.sizeof(lltype.UniChar) + else: + unichar_size = 2 if sys.maxunicode == 0xFFFF else 4 + return unichar_size == 2 and rffi.sizeof(rffi.WCHAR_T) == 4 From noreply at buildbot.pypy.org Sun Sep 15 00:45:38 2013 From: noreply at buildbot.pypy.org (mattip) Date: Sun, 15 Sep 2013 00:45:38 +0200 (CEST) Subject: [pypy-commit] pypy default: skip test for non-implemented unicode box Message-ID: <20130914224538.C10711C016D@cobra.cs.uni-duesseldorf.de> Author: mattip Branch: Changeset: r66949:c505716d0bea Date: 2013-09-15 01:43 +0300 http://bitbucket.org/pypy/pypy/changeset/c505716d0bea/ Log: skip test for non-implemented unicode box 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 @@ -776,7 +776,13 @@ def test_unicode_boxes(self): from numpypy import unicode_ - assert isinstance(unicode_(3), unicode) + try: + u = unicode_(3) + except NotImplementedError, e: + if e.message.find('not supported yet') >= 0: + skip('unicode box not implemented') + else: + assert isinstance(u, unicode) def test_character_dtype(self): from numpypy import array, character From noreply at buildbot.pypy.org Sun Sep 15 12:23:10 2013 From: noreply at buildbot.pypy.org (arigo) Date: Sun, 15 Sep 2013 12:23:10 +0200 (CEST) Subject: [pypy-commit] pypy stmgc-static-barrier: import stmgc/111c09337109 Message-ID: <20130915102310.3A5F91C0162@cobra.cs.uni-duesseldorf.de> Author: Armin Rigo Branch: stmgc-static-barrier Changeset: r66950:c92df32a39c0 Date: 2013-09-15 10:35 +0200 http://bitbucket.org/pypy/pypy/changeset/c92df32a39c0/ Log: import stmgc/111c09337109 diff --git a/rpython/translator/stm/src_stm/dbgmem.c b/rpython/translator/stm/src_stm/dbgmem.c --- a/rpython/translator/stm/src_stm/dbgmem.c +++ b/rpython/translator/stm/src_stm/dbgmem.c @@ -4,12 +4,12 @@ #define PAGE_SIZE 4096 - +#define MEM_SIZE(mem) (*(((size_t *)(mem)) - 1)) #ifdef _GC_DEBUG /************************************************************/ -#define MMAP_TOTAL 1280*1024*1024 /* 1280MB */ +#define MMAP_TOTAL 2000*1024*1024 /* 2000MB */ static pthread_mutex_t malloc_mutex = PTHREAD_MUTEX_INITIALIZER; static char *zone_start, *zone_current = NULL, *zone_end = NULL; @@ -32,8 +32,10 @@ void *stm_malloc(size_t sz) { + size_t real_sz = sz + sizeof(size_t); + +#ifdef _GC_MEMPROTECT pthread_mutex_lock(&malloc_mutex); - if (zone_current == NULL) { zone_start = mmap(NULL, MMAP_TOTAL, PROT_NONE, MAP_PRIVATE | MAP_ANONYMOUS, -1, 0); @@ -43,10 +45,11 @@ zone_current = zone_start; zone_end = zone_start + MMAP_TOTAL; assert((MMAP_TOTAL % PAGE_SIZE) == 0); + _stm_dbgmem(zone_start, MMAP_TOTAL, PROT_NONE); } - size_t nb_pages = (sz + PAGE_SIZE - 1) / PAGE_SIZE + 1; + size_t nb_pages = (real_sz + PAGE_SIZE - 1) / PAGE_SIZE + 1; char *result = zone_current; zone_current += nb_pages * PAGE_SIZE; if (zone_current > zone_end) { @@ -55,50 +58,67 @@ } pthread_mutex_unlock(&malloc_mutex); - result += (-sz) & (PAGE_SIZE-1); - assert(((intptr_t)(result + sz) & (PAGE_SIZE-1)) == 0); - _stm_dbgmem(result, sz, PROT_READ | PROT_WRITE); + result += (-real_sz) & (PAGE_SIZE-1); + assert(((intptr_t)(result + real_sz) & (PAGE_SIZE-1)) == 0); + _stm_dbgmem(result, real_sz, PROT_READ | PROT_WRITE); long i, base = (result - zone_start) / PAGE_SIZE; for (i = 0; i < nb_pages; i++) accessible_pages[base + i] = 42; + assert(((intptr_t)(result + real_sz) & (PAGE_SIZE-1)) == 0); +#else + char * result = malloc(real_sz); +#endif + dprintf(("stm_malloc(%zu): %p\n", sz, result)); - assert(((intptr_t)(result + sz) & (PAGE_SIZE-1)) == 0); - memset(result, 0xBB, sz); + memset(result, 0xBB, real_sz); + + result += sizeof(size_t); + MEM_SIZE(result) = real_sz; return result; } -void stm_free(void *p, size_t sz) +void stm_free(void *p) { if (p == NULL) { - assert(sz == 0); return; } - assert(((intptr_t)((char *)p + sz) & (PAGE_SIZE-1)) == 0); + size_t real_sz = MEM_SIZE(p); + void *real_p = p - sizeof(size_t); + assert(real_sz > 0); - size_t nb_pages = (sz + PAGE_SIZE - 1) / PAGE_SIZE + 1; - long i, base = ((char *)p - zone_start) / PAGE_SIZE; + memset(real_p, 0xDD, real_sz); +#ifdef _GC_MEMPROTECT + assert(((intptr_t)((char *)real_p + real_sz) & (PAGE_SIZE-1)) == 0); + + size_t nb_pages = (real_sz + PAGE_SIZE - 1) / PAGE_SIZE + 1; + long i, base = ((char *)real_p - zone_start) / PAGE_SIZE; assert(0 <= base && base < (MMAP_TOTAL / PAGE_SIZE)); for (i = 0; i < nb_pages; i++) { assert(accessible_pages[base + i] == 42); accessible_pages[base + i] = -1; } - memset(p, 0xDD, sz); - _stm_dbgmem(p, sz, PROT_NONE); + + _stm_dbgmem(real_p, real_sz, PROT_NONE); +#endif } void *stm_realloc(void *p, size_t newsz, size_t oldsz) { void *r = stm_malloc(newsz); memcpy(r, p, oldsz < newsz ? oldsz : newsz); - stm_free(p, oldsz); + stm_free(p); return r; } int _stm_can_access_memory(char *p) { - long base = ((char *)p - zone_start) / PAGE_SIZE; +#ifndef _GC_MEMPROTECT + assert(0); /* tests must use MEMPROTECT */ +#endif + char* real_p = p - sizeof(size_t); + long base = ((char *)real_p - zone_start) / PAGE_SIZE; assert(0 <= base && base < (MMAP_TOTAL / PAGE_SIZE)); return accessible_pages[base] == 42; } diff --git a/rpython/translator/stm/src_stm/dbgmem.h b/rpython/translator/stm/src_stm/dbgmem.h --- a/rpython/translator/stm/src_stm/dbgmem.h +++ b/rpython/translator/stm/src_stm/dbgmem.h @@ -6,7 +6,7 @@ #ifdef _GC_DEBUG void *stm_malloc(size_t); -void stm_free(void *, size_t); +void stm_free(void *); void *stm_realloc(void *, size_t, size_t); int _stm_can_access_memory(char *); void assert_cleared(char *, size_t); @@ -14,7 +14,7 @@ #else #define stm_malloc(sz) malloc(sz) -#define stm_free(p,sz) free(p) +#define stm_free(p) free(p) #define stm_realloc(p,newsz,oldsz) realloc(p,newsz) #define assert_cleared(p,sz) do { } while(0) diff --git a/rpython/translator/stm/src_stm/et.c b/rpython/translator/stm/src_stm/et.c --- a/rpython/translator/stm/src_stm/et.c +++ b/rpython/translator/stm/src_stm/et.c @@ -16,7 +16,7 @@ i = 0; cur = tmp_buf; - cur += sprintf(cur, "%p:", obj); + cur += sprintf(cur, "%p : ", obj); while (flags[i]) { if (obj->h_tid & (STM_FIRST_GCFLAG << i)) { cur += sprintf(cur, "%s|", flags[i]); @@ -24,9 +24,36 @@ i++; } cur += sprintf(cur, "tid=%ld", stm_get_tid(obj)); + cur += sprintf(cur, " : rev=%lx : orig=%lx", + (long)obj->h_revision, (long)obj->h_original); return tmp_buf; } +void stm_dump_dbg(void) +{ + fprintf(stderr, "/**** stm_dump_dbg ****/\n\n"); + + int i; + for (i = 0; i < MAX_THREADS; i++) { + struct tx_public_descriptor *pd = stm_descriptor_array[i]; + if (pd == NULL) + continue; + fprintf(stderr, "stm_descriptor_array[%d]\n((struct tx_public_descriptor *)%p)\n", + i, pd); + + struct tx_descriptor *d = stm_tx_head; + while (d && d->public_descriptor != pd) + d = d->tx_next; + if (!d) + continue; + + fprintf(stderr, "((struct tx_descriptor *)\033[%dm%p\033[0m)\n" + "pthread_self = 0x%lx\n\n", d->tcolor, d, (long)d->pthreadid); + } + + fprintf(stderr, "/**********************/\n"); +} + __thread struct tx_descriptor *thread_descriptor = NULL; @@ -109,6 +136,7 @@ revision_t v; d->count_reads++; + assert(IMPLIES(!(P->h_tid & GCFLAG_OLD), stmgc_is_in_nursery(d, P))); restart_all: if (P->h_tid & GCFLAG_PRIVATE_FROM_PROTECTED) @@ -281,6 +309,9 @@ */ assert(P->h_tid & GCFLAG_PUBLIC); assert(!(P->h_tid & GCFLAG_STUB)); + assert(IMPLIES(!(P->h_tid & GCFLAG_OLD), + stmgc_is_in_nursery(thread_descriptor, P))); + if (P->h_tid & GCFLAG_MOVED) { @@ -321,6 +352,9 @@ { assert(P->h_tid & GCFLAG_STUB); assert(P->h_tid & GCFLAG_PUBLIC); + assert(IMPLIES(!(P->h_tid & GCFLAG_OLD), + stmgc_is_in_nursery(thread_descriptor, P))); + revision_t v = ACCESS_ONCE(P->h_revision); assert(IS_POINTER(v)); /* "is a pointer", "has a more recent revision" */ @@ -569,6 +603,7 @@ not_found: #endif + assert(!(R->h_tid & GCFLAG_STUB)); R->h_tid |= GCFLAG_PUBLIC_TO_PRIVATE; /* note that stmgc_duplicate() usually returns a young object, but may @@ -589,6 +624,7 @@ assert(!(L->h_tid & GCFLAG_STUB)); assert(!(L->h_tid & GCFLAG_PRIVATE_FROM_PROTECTED)); L->h_tid &= ~(GCFLAG_VISITED | + GCFLAG_MARKED | GCFLAG_PUBLIC | GCFLAG_PREBUILT_ORIGINAL | GCFLAG_PUBLIC_TO_PRIVATE | @@ -610,8 +646,12 @@ static inline void record_write_barrier(gcptr P) { + assert(is_private(P)); + assert(IMPLIES(!(P->h_tid & GCFLAG_OLD), + stmgc_is_in_nursery(thread_descriptor, P))); if (P->h_tid & GCFLAG_WRITE_BARRIER) { + assert(P->h_tid & GCFLAG_OLD); P->h_tid &= ~GCFLAG_WRITE_BARRIER; gcptrlist_insert(&thread_descriptor->old_objects_to_trace, P); } @@ -619,6 +659,9 @@ gcptr stm_RepeatWriteBarrier(gcptr P) { + assert(IMPLIES(!(P->h_tid & GCFLAG_OLD), + stmgc_is_in_nursery(thread_descriptor, P))); + assert(!(P->h_tid & GCFLAG_IMMUTABLE)); assert(is_private(P)); assert(P->h_tid & GCFLAG_WRITE_BARRIER); @@ -637,6 +680,9 @@ over it. However such objects are so small that they contain no field at all, and so no write barrier should occur on them. */ + assert(IMPLIES(!(P->h_tid & GCFLAG_OLD), + stmgc_is_in_nursery(thread_descriptor, P))); + if (is_private(P)) { /* If we have GCFLAG_WRITE_BARRIER in P, then list it into @@ -857,6 +903,7 @@ void AbortTransaction(int num) { + static const char *abort_names[] = ABORT_NAMES; struct tx_descriptor *d = thread_descriptor; unsigned long limit; struct timespec now; @@ -905,8 +952,8 @@ d->longest_abort_info_time = 0; /* out of memory! */ else { - if (stm_decode_abort_info(d, elapsed_time, - num, d->longest_abort_info) != size) + if (stm_decode_abort_info(d, elapsed_time, num, + (struct tx_abort_info *)d->longest_abort_info) != size) stm_fatalerror("during stm abort: object mutated unexpectedly\n"); d->longest_abort_info_time = elapsed_time; @@ -937,28 +984,38 @@ stm_thread_local_obj = d->old_thread_local_obj; d->old_thread_local_obj = NULL; + // notifies the CPU that we're potentially in a spin loop + SpinLoop(SPLP_ABORT); + + /* make the transaction no longer active */ + d->active = 0; + d->atomic = 0; + /* release the lock */ spinlock_release(d->public_descriptor->collection_lock); /* clear memory registered by stm_clear_on_abort */ - if (stm_to_clear_on_abort) - memset(stm_to_clear_on_abort, 0, stm_bytes_to_clear_on_abort); + if (d->mem_clear_on_abort) + memset(d->mem_clear_on_abort, 0, d->mem_bytes_to_clear_on_abort); + /* invoke the callbacks registered by stm_call_on_abort */ + stm_invoke_callbacks_on_abort(d); + stm_clear_callbacks_on_abort(d); + + /* XXX */ + fprintf(stderr, "[%lx] abort %s\n", + (long)d->public_descriptor_index, abort_names[num]); dprintf(("\n" "!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!\n" "!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!\n" - "!!!!!!!!!!!!!!!!!!!!! [%lx] abort %d\n" + "!!!!!!!!!!!!!!!!!!!!! [%lx] abort %s\n" "!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!\n" "!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!\n" - "\n", (long)d->public_descriptor_index, num)); + "\n", (long)d->public_descriptor_index, abort_names[num])); if (num != ABRT_MANUAL && d->max_aborts >= 0 && !d->max_aborts--) stm_fatalerror("unexpected abort!\n"); - // notifies the CPU that we're potentially in a spin loop - SpinLoop(SPLP_ABORT); // jump back to the setjmp_buf (this call does not return) - d->active = 0; - d->atomic = 0; stm_stop_sharedlock(); longjmp(*d->setjmp_buf, 1); } @@ -1437,6 +1494,10 @@ d->num_commits++; d->active = 0; stm_stop_sharedlock(); + + /* clear the list of callbacks that would have been called + on abort */ + stm_clear_callbacks_on_abort(d); } /************************************************************/ @@ -1477,6 +1538,9 @@ (XXX statically we should know when we're outside a transaction) */ + /* XXX */ + fprintf(stderr, "[%lx] inevitable: %s\n", + (long)d->public_descriptor_index, why); dprintf(("[%lx] inevitable: %s\n", (long)d->public_descriptor_index, why)); @@ -1673,6 +1737,8 @@ stm_thread_local_obj = NULL; d->thread_local_obj_ref = &stm_thread_local_obj; d->max_aborts = -1; + d->tcolor = dprintfcolor(); + d->pthreadid = pthread_self(); d->tx_prev = NULL; d->tx_next = stm_tx_head; if (d->tx_next != NULL) d->tx_next->tx_prev = d; @@ -1746,5 +1812,5 @@ p += sprintf(p, "]\n"); dprintf(("%s", line)); - stm_free(d, sizeof(struct tx_descriptor)); + stm_free(d); } 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 @@ -65,6 +65,10 @@ * * GCFLAG_HAS_ID is set on young objects that have an old reserved * memory to be copied to in minor collections (obj->h_original) + * + * GCFLAG_WEAKREF is set on weakrefs. Only needed so that we can trace + * the weakptr when stealing a weakref. Maybe a better solution is to + * check the typeid? */ static const revision_t GCFLAG_OLD = STM_FIRST_GCFLAG << 0; static const revision_t GCFLAG_VISITED = STM_FIRST_GCFLAG << 1; @@ -80,6 +84,7 @@ static const revision_t GCFLAG_IMMUTABLE = STM_FIRST_GCFLAG << 11; static const revision_t GCFLAG_SMALLSTUB /*debug*/ = STM_FIRST_GCFLAG << 12; static const revision_t GCFLAG_MARKED = STM_FIRST_GCFLAG << 13; +static const revision_t GCFLAG_WEAKREF = STM_FIRST_GCFLAG << 14; /* warning, the last flag available is "<< 15" on 32-bit */ @@ -104,6 +109,7 @@ "IMMUTABLE", \ "SMALLSTUB", \ "MARKED", \ + "WEAKREF", \ NULL } #define IS_POINTER(v) (!((v) & 1)) /* even-valued number */ @@ -119,6 +125,15 @@ #define ABRT_COLLECT_MINOR 6 #define ABRT_COLLECT_MAJOR 7 #define ABORT_REASONS 8 +#define ABORT_NAMES { "MANUAL", \ + "COMMIT", \ + "STOLEN_MODIFIED", \ + "VALIDATE_INFLIGHT", \ + "VALIDATE_COMMIT", \ + "VALIDATE_INEV", \ + "COLLECT_MINOR", \ + "COLLECT_MAJOR", \ + } #define SPLP_ABORT 0 #define SPLP_LOCKED_INFLIGHT 1 @@ -176,6 +191,11 @@ struct FXCache recent_reads_cache; char **read_barrier_cache_ref; struct tx_descriptor *tx_prev, *tx_next; + int tcolor; + pthread_t pthreadid; + void *mem_clear_on_abort; + size_t mem_bytes_to_clear_on_abort; + struct G2L callbacks_on_abort; }; extern __thread struct tx_descriptor *thread_descriptor; diff --git a/rpython/translator/stm/src_stm/extra.c b/rpython/translator/stm/src_stm/extra.c --- a/rpython/translator/stm/src_stm/extra.c +++ b/rpython/translator/stm/src_stm/extra.c @@ -15,13 +15,53 @@ } -__thread void *stm_to_clear_on_abort = NULL; -__thread size_t stm_bytes_to_clear_on_abort; - void stm_clear_on_abort(void *start, size_t bytes) { - stm_to_clear_on_abort = start; - stm_bytes_to_clear_on_abort = bytes; + struct tx_descriptor *d = thread_descriptor; + assert(d != NULL); + d->mem_clear_on_abort = start; + d->mem_bytes_to_clear_on_abort = bytes; +} + +void stm_call_on_abort(void *key, void callback(void *)) +{ + struct tx_descriptor *d = thread_descriptor; + if (d == NULL || d->active != 1) + return; /* ignore callbacks if we're outside a transaction or + in an inevitable transaction (which cannot abort) */ + if (callback == NULL) { + /* ignore the return value: unregistered keys can be + "deleted" again */ + g2l_delete_item(&d->callbacks_on_abort, (gcptr)key); + } + else { + /* double-registering the same key will crash */ + g2l_insert(&d->callbacks_on_abort, (gcptr)key, (gcptr)callback); + } +} + +void stm_clear_callbacks_on_abort(struct tx_descriptor *d) +{ + if (g2l_any_entry(&d->callbacks_on_abort)) + g2l_clear(&d->callbacks_on_abort); +} + +void stm_invoke_callbacks_on_abort(struct tx_descriptor *d) +{ + wlog_t *item; + assert(d->active == 0); + + G2L_LOOP_FORWARD(d->callbacks_on_abort, item) { + void *key = (void *)item->addr; + void (*callback)(void *) = (void(*)(void *))item->val; + assert(key != NULL); + assert(callback != NULL); + + /* The callback may call stm_call_on_abort(key, NULL). + It is ignored, because we're no longer active. */ + callback(key); + + } G2L_LOOP_END; } @@ -42,7 +82,8 @@ stm_minor_collect(); obj = stm_pop_root(); } - + assert(obj->h_tid & GCFLAG_OLD); + spinlock_acquire(d->public_descriptor->collection_lock, 'P'); stub = stm_stub_malloc(d->public_descriptor, 0); @@ -178,6 +219,8 @@ if (p->h_tid & GCFLAG_PRIVATE_FROM_PROTECTED) { gcptr B = (gcptr)p->h_revision; + /* not stolen already: */ + assert(!(B->h_tid & GCFLAG_PUBLIC)); B->h_original = (revision_t)O; } @@ -233,13 +276,75 @@ } size_t stm_decode_abort_info(struct tx_descriptor *d, long long elapsed_time, - int abort_reason, char *output) + int abort_reason, struct tx_abort_info *output) { - /* re-encodes the abort info as a single string. + /* Re-encodes the abort info as a single tx_abort_info structure. + This struct tx_abort_info is not visible to the outside, and used + only as an intermediate format that is fast to generate and without + requiring stm_read_barrier(). + */ + if (output != NULL) { + output->signature_packed = 127; + output->elapsed_time = elapsed_time; + output->abort_reason = abort_reason; + output->active = d->active; + output->atomic = d->atomic; + output->count_reads = d->count_reads; + output->reads_size_limit_nonatomic = d->reads_size_limit_nonatomic; + } + + long num_words = 0; +#define WRITE_WORD(word) { \ + if (output) output->words[num_words] = (word); \ + num_words++; \ + } + + long i; + for (i=0; iabortinfo.size; i+=2) { + char *object = (char*)stm_repeat_read_barrier(d->abortinfo.items[i+0]); + long *fieldoffsets = (long*)d->abortinfo.items[i+1]; + long kind, offset; + while (*fieldoffsets != 0) { + kind = *fieldoffsets++; + WRITE_WORD(kind); + if (kind < 0) { + /* -1 is start of sublist; -2 is end of sublist */ + continue; + } + offset = *fieldoffsets++; + switch(kind) { + case 1: /* signed */ + case 2: /* unsigned */ + WRITE_WORD(*(long *)(object + offset)); + break; + case 3: /* a string of bytes from the target object */ + WRITE_WORD((revision_t)*(char **)(object + offset)); + offset = *fieldoffsets++; /* offset of len in the string */ + WRITE_WORD(offset); + break; + default: + stm_fatalerror("corrupted abort log\n"); + } + } + } + WRITE_WORD(0); +#undef WRITE_WORD + return sizeof(struct tx_abort_info) + (num_words - 1) * sizeof(revision_t); +} + +static size_t unpack_abort_info(struct tx_descriptor *d, + struct tx_abort_info *ai, + char *output) +{ + /* Lazily decodes a struct tx_abort_info into a single plain string. For convenience (no escaping needed, no limit on integer - sizes, etc.) we follow the bittorrent format. */ + sizes, etc.) we follow the bittorrent format. This makes the + format a bit more flexible for future changes. The struct + tx_abort_info is still needed as an intermediate step, because + the string parameters may not be readable during an abort + (they may be stubs). + */ size_t totalsize = 0; - long i; char buffer[32]; size_t res_size; #define WRITE(c) { totalsize++; if (output) *output++=(c); } @@ -250,74 +355,74 @@ } WRITE('l'); WRITE('l'); - res_size = sprintf(buffer, "i%llde", (long long)elapsed_time); + res_size = sprintf(buffer, "i%llde", (long long)ai->elapsed_time); WRITE_BUF(buffer, res_size); - res_size = sprintf(buffer, "i%de", (int)abort_reason); + res_size = sprintf(buffer, "i%de", (int)ai->abort_reason); WRITE_BUF(buffer, res_size); res_size = sprintf(buffer, "i%lde", (long)d->public_descriptor_index); WRITE_BUF(buffer, res_size); - res_size = sprintf(buffer, "i%lde", (long)d->atomic); + res_size = sprintf(buffer, "i%lde", (long)ai->atomic); WRITE_BUF(buffer, res_size); - res_size = sprintf(buffer, "i%de", (int)d->active); + res_size = sprintf(buffer, "i%de", (int)ai->active); WRITE_BUF(buffer, res_size); - res_size = sprintf(buffer, "i%lue", (unsigned long)d->count_reads); + res_size = sprintf(buffer, "i%lue", (unsigned long)ai->count_reads); WRITE_BUF(buffer, res_size); res_size = sprintf(buffer, "i%lue", - (unsigned long)d->reads_size_limit_nonatomic); + (unsigned long)ai->reads_size_limit_nonatomic); WRITE_BUF(buffer, res_size); WRITE('e'); - for (i=0; iabortinfo.size; i+=2) { - char *object = (char*)stm_repeat_read_barrier(d->abortinfo.items[i+0]); - long *fieldoffsets = (long*)d->abortinfo.items[i+1]; - long kind, offset; - size_t rps_size; + + revision_t *src = ai->words; + while (*src != 0) { + long signed_value; + unsigned long unsigned_value; char *rps; + long offset, rps_size; - while (1) { - kind = *fieldoffsets++; - if (kind <= 0) { - if (kind == -2) { - WRITE('l'); /* '[', start of sublist */ - continue; - } - if (kind == -1) { - WRITE('e'); /* ']', end of sublist */ - continue; - } - break; /* 0, terminator */ + switch (*src++) { + + case -2: + WRITE('l'); /* '[', start of sublist */ + break; + + case -1: + WRITE('e'); /* ']', end of sublist */ + break; + + case 1: /* signed */ + signed_value = (long)(*src++); + res_size = sprintf(buffer, "i%lde", signed_value); + WRITE_BUF(buffer, res_size); + break; + + case 2: /* unsigned */ + unsigned_value = (unsigned long)(*src++); + res_size = sprintf(buffer, "i%lue", unsigned_value); + WRITE_BUF(buffer, res_size); + break; + + case 3: /* a string of bytes from the target object */ + rps = (char *)(*src++); + offset = *src++; + if (rps) { + rps = (char *)stm_read_barrier((gcptr)rps); + /* xxx a bit ad-hoc: it's a string whose length is a + * long at 'rps_size'; the string data follows + * immediately the length */ + rps_size = *(long *)(rps + offset); + assert(rps_size >= 0); + res_size = sprintf(buffer, "%ld:", rps_size); + WRITE_BUF(buffer, res_size); + WRITE_BUF(rps + offset + sizeof(long), rps_size); } - offset = *fieldoffsets++; - switch(kind) { - case 1: /* signed */ - res_size = sprintf(buffer, "i%lde", - *(long*)(object + offset)); - WRITE_BUF(buffer, res_size); - break; - case 2: /* unsigned */ - res_size = sprintf(buffer, "i%lue", - *(unsigned long*)(object + offset)); - WRITE_BUF(buffer, res_size); - break; - case 3: /* a string of bytes from the target object */ - rps = *(char **)(object + offset); - offset = *fieldoffsets++; - if (rps) { - /* xxx a bit ad-hoc: it's a string whose length is a - * long at 'offset', following immediately the offset */ - rps_size = *(long *)(rps + offset); - offset += sizeof(long); - assert(rps_size >= 0); - res_size = sprintf(buffer, "%zu:", rps_size); - WRITE_BUF(buffer, res_size); - WRITE_BUF(rps + offset, rps_size); - } - else { - WRITE_BUF("0:", 2); - } - break; - default: - stm_fatalerror("corrupted abort log\n"); + else { + /* write NULL as an empty string, good enough for now */ + WRITE_BUF("0:", 2); } + break; + + default: + stm_fatalerror("corrupted abort log\n"); } } WRITE('e'); @@ -332,6 +437,53 @@ struct tx_descriptor *d = thread_descriptor; if (d->longest_abort_info_time <= 0) return NULL; + + struct tx_abort_info *ai = (struct tx_abort_info *)d->longest_abort_info; + assert(ai->signature_packed == 127); + + stm_become_inevitable("stm_inspect_abort_info"); + + size_t size = unpack_abort_info(d, ai, NULL); + char *text = malloc(size); + if (text == NULL) + return NULL; /* out of memory */ + if (unpack_abort_info(d, ai, text) != size) + stm_fatalerror("stm_inspect_abort_info: " + "object mutated unexpectedly\n"); + free(ai); + d->longest_abort_info = text; d->longest_abort_info_time = 0; return d->longest_abort_info; } + +void stm_visit_abort_info(struct tx_descriptor *d, void (*visit)(gcptr *)) +{ + long i, size = d->abortinfo.size; + gcptr *items = d->abortinfo.items; + for (i = 0; i < size; i += 2) { + visit(&items[i]); + /* items[i+1] is not a gc ptr */ + } + + struct tx_abort_info *ai = (struct tx_abort_info *)d->longest_abort_info; + if (ai != NULL && ai->signature_packed == 127) { + revision_t *src = ai->words; + while (*src != 0) { + gcptr *rpps; + + switch (*src++) { + + case 1: /* signed */ + case 2: /* unsigned */ + src++; /* ignore the value */ + break; + + case 3: + rpps = (gcptr *)(src++); + src++; /* ignore the offset */ + visit(rpps); /* visit() the string object */ + break; + } + } + } +} diff --git a/rpython/translator/stm/src_stm/extra.h b/rpython/translator/stm/src_stm/extra.h --- a/rpython/translator/stm/src_stm/extra.h +++ b/rpython/translator/stm/src_stm/extra.h @@ -3,8 +3,22 @@ #define _SRCSTM_EXTRA_H +struct tx_abort_info { + char signature_packed; /* 127 when the abort_info is in this format */ + long long elapsed_time; + int abort_reason; + int active; + long atomic; + unsigned long count_reads; + unsigned long reads_size_limit_nonatomic; + revision_t words[1]; /* the 'words' list is a bytecode-like format */ +}; + void stm_copy_to_old_id_copy(gcptr obj, gcptr id); size_t stm_decode_abort_info(struct tx_descriptor *d, long long elapsed_time, - int abort_reason, char *output); + int abort_reason, struct tx_abort_info *output); +void stm_visit_abort_info(struct tx_descriptor *d, void (*visit)(gcptr *)); +void stm_clear_callbacks_on_abort(struct tx_descriptor *d); +void stm_invoke_callbacks_on_abort(struct tx_descriptor *d); #endif diff --git a/rpython/translator/stm/src_stm/gcpage.c b/rpython/translator/stm/src_stm/gcpage.c --- a/rpython/translator/stm/src_stm/gcpage.c +++ b/rpython/translator/stm/src_stm/gcpage.c @@ -208,8 +208,9 @@ //stm_dbgmem_not_used(obj, size_class * WORD, 0); } else { - g2l_delete_item(&gcp->nonsmall_objects, obj); - stm_free(obj, size); + int deleted = g2l_delete_item(&gcp->nonsmall_objects, obj); + assert(deleted); + stm_free(obj); } } @@ -235,7 +236,8 @@ assert(obj->h_tid & GCFLAG_PUBLIC); stmgcpage_acquire_global_lock(); - g2l_delete_item(®istered_stubs, obj); + int deleted = g2l_delete_item(®istered_stubs, obj); + assert(deleted); stmgcpage_release_global_lock(); dprintf(("unregistered %p\n", obj)); } @@ -416,6 +418,7 @@ } else if (obj != original) { /* copy obj over original */ + assert(obj->h_original == (revision_t)original); copy_over_original(obj, original); } @@ -496,15 +499,27 @@ static void mark_registered_stubs(void) { wlog_t *item; + gcptr L; + G2L_LOOP_FORWARD(registered_stubs, item) { gcptr R = item->addr; assert(R->h_tid & GCFLAG_SMALLSTUB); + /* The following assert can fail if we have a stub pointing to + a stub and both are registered_stubs. This case is benign. */ + //assert(!(R->h_tid & (GCFLAG_VISITED | GCFLAG_MARKED))); R->h_tid |= (GCFLAG_MARKED | GCFLAG_VISITED); - gcptr L = (gcptr)(R->h_revision - 2); - L = stmgcpage_visit(L); - R->h_revision = ((revision_t)L) | 2; + if (R->h_revision & 2) { + L = (gcptr)(R->h_revision - 2); + L = stmgcpage_visit(L); + R->h_revision = ((revision_t)L) | 2; + } + else { + L = (gcptr)R->h_revision; + L = stmgcpage_visit(L); + R->h_revision = (revision_t)L; + } /* h_original will be kept up-to-date because it is either == L or L's h_original. And @@ -552,12 +567,7 @@ visit_take_protected(&d->old_thread_local_obj); /* the abortinfo objects */ - long i, size = d->abortinfo.size; - gcptr *items = d->abortinfo.items; - for (i = 0; i < size; i += 2) { - visit_take_protected(&items[i]); - /* items[i+1] is not a gc ptr */ - } + stm_visit_abort_info(d, &visit_take_protected); /* the current transaction's private copies of public objects */ wlog_t *item; @@ -590,8 +600,8 @@ } G2L_LOOP_END; /* reinsert to real pub_to_priv */ - size = new_public_to_private.size; - items = new_public_to_private.items; + long i, size = new_public_to_private.size; + gcptr *items = new_public_to_private.items; for (i = 0; i < size; i += 2) { g2l_insert(&d->public_to_private, items[i], items[i + 1]); } @@ -809,7 +819,7 @@ p = (gcptr)(((char *)p) + obj_size); } #endif - stm_free(lpage, GC_PAGE_SIZE); + stm_free(lpage); assert(gcp->count_pages > 0); assert(count_global_pages > 0); gcp->count_pages--; @@ -839,7 +849,7 @@ } else { G2L_LOOP_DELETE(item); - stm_free(p, stmgc_size(p)); + stm_free(p); } } G2L_LOOP_END_AND_COMPRESS; @@ -954,10 +964,14 @@ mark_prebuilt_roots(); mark_registered_stubs(); mark_all_stack_roots(); + + /* weakrefs: */ do { visit_all_objects(); + stm_update_old_weakrefs_lists(); stm_visit_old_weakrefs(); } while (gcptrlist_size(&objects_to_trace) != 0); + gcptrlist_delete(&objects_to_trace); clean_up_lists_of_read_objects_and_fix_outdated_flags(); stm_clean_old_weakrefs(); diff --git a/rpython/translator/stm/src_stm/lists.c b/rpython/translator/stm/src_stm/lists.c --- a/rpython/translator/stm/src_stm/lists.c +++ b/rpython/translator/stm/src_stm/lists.c @@ -19,7 +19,7 @@ void g2l_delete(struct G2L *g2l) { - stm_free(g2l->raw_start, g2l->raw_end - g2l->raw_start); + stm_free(g2l->raw_start); memset(g2l, 0, sizeof(struct G2L)); } @@ -66,7 +66,7 @@ { g2l_insert(&newg2l, item->addr, item->val); } G2L_LOOP_END; - stm_free(g2l->raw_start, g2l->raw_end - g2l->raw_start); + stm_free(g2l->raw_start); *g2l = newg2l; } @@ -91,7 +91,6 @@ int shift = 0; char *p = (char *)(g2l->toplevel.items); char *entry; - assert((key & (sizeof(void*)-1)) == 0); /* only for aligned keys */ while (1) { p += (key >> shift) & TREE_MASK; @@ -133,15 +132,15 @@ *(char **)p = (char *)wlog; } -void g2l_delete_item(struct G2L *g2l, gcptr addr) +int g2l_delete_item(struct G2L *g2l, gcptr addr) { wlog_t *entry; G2L_FIND(*g2l, addr, entry, goto missing); entry->addr = NULL; - return; + return 1; missing: - stm_fatalerror("g2l_delete_item: item %p not in dict", addr); + return 0; } /************************************************************/ @@ -152,7 +151,7 @@ //fprintf(stderr, "list %p deleted (%ld KB)\n", //gcptrlist, gcptrlist->alloc * sizeof(gcptr) / 1024); gcptrlist->size = 0; - stm_free(gcptrlist->items, gcptrlist->alloc * sizeof(gcptr)); + stm_free(gcptrlist->items); gcptrlist->items = NULL; gcptrlist->alloc = 0; } @@ -183,7 +182,7 @@ long i; for (i=0; isize; i++) newitems[i] = gcptrlist->items[i]; - stm_free(gcptrlist->items, gcptrlist->alloc * sizeof(gcptr)); + stm_free(gcptrlist->items); gcptrlist->items = newitems; gcptrlist->alloc = newalloc; } diff --git a/rpython/translator/stm/src_stm/lists.h b/rpython/translator/stm/src_stm/lists.h --- a/rpython/translator/stm/src_stm/lists.h +++ b/rpython/translator/stm/src_stm/lists.h @@ -39,7 +39,7 @@ void g2l_clear(struct G2L *g2l); void g2l_delete(struct G2L *g2l); static inline void g2l_delete_not_used_any_more(struct G2L *g2l) { - stm_free(g2l->raw_start, g2l->raw_end - g2l->raw_start); + stm_free(g2l->raw_start); } static inline int g2l_any_entry(struct G2L *g2l) { @@ -114,7 +114,7 @@ wlog_t *_g2l_find(char *entry, gcptr addr); void _g2l_compress(struct G2L *g2l); void g2l_insert(struct G2L *g2l, gcptr addr, gcptr val); -void g2l_delete_item(struct G2L *g2l, gcptr addr); +int g2l_delete_item(struct G2L *g2l, gcptr addr); static inline int g2l_contains(struct G2L *g2l, gcptr addr) { diff --git a/rpython/translator/stm/src_stm/nursery.c b/rpython/translator/stm/src_stm/nursery.c --- a/rpython/translator/stm/src_stm/nursery.c +++ b/rpython/translator/stm/src_stm/nursery.c @@ -50,7 +50,7 @@ updatechainheads() -> stub_malloc() -> ...): */ assert(!minor_collect_anything_to_do(d) || d->nursery_current == d->nursery_end); - stm_free(d->nursery_base, GC_NURSERY); + stm_free(d->nursery_base); gcptrlist_delete(&d->old_objects_to_trace); gcptrlist_delete(&d->public_with_young_copy); @@ -95,6 +95,7 @@ { /* XXX inline the fast path */ assert(tid == (tid & STM_USER_TID_MASK)); + assert(thread_descriptor->active > 0); gcptr P = allocate_nursery(size, tid); P->h_revision = stm_private_rev_num; assert(P->h_original == 0); /* null-initialized already */ @@ -156,6 +157,7 @@ struct tx_descriptor *d = thread_descriptor; if (!stmgc_is_in_nursery(d, obj)) { + assert(IMPLIES(obj, obj->h_tid & GCFLAG_OLD)); /* not a nursery object */ } else { @@ -454,12 +456,7 @@ visit_if_young(d->thread_local_obj_ref); visit_if_young(&d->old_thread_local_obj); - long i, size = d->abortinfo.size; - gcptr *items = d->abortinfo.items; - for (i = 0; i < size; i += 2) { - visit_if_young(&items[i]); - /* items[i+1] is not a gc ptr */ - } + stm_visit_abort_info(d, &visit_if_young); } static void minor_collect(struct tx_descriptor *d) @@ -524,7 +521,7 @@ #if defined(_GC_DEBUG) && _GC_DEBUG >= 2 if (d->nursery_cleared == NC_ALREADY_CLEARED) assert_cleared(d->nursery_base, GC_NURSERY); - stm_free(d->nursery_base, GC_NURSERY); + stm_free(d->nursery_base); d->nursery_base = stm_malloc(GC_NURSERY); d->nursery_end = d->nursery_base + GC_NURSERY; dprintf(("minor: nursery moved to [%p to %p]\n", d->nursery_base, diff --git a/rpython/translator/stm/src_stm/revision b/rpython/translator/stm/src_stm/revision --- a/rpython/translator/stm/src_stm/revision +++ b/rpython/translator/stm/src_stm/revision @@ -1,1 +1,1 @@ -d2e01fce511f +111c09337109 diff --git a/rpython/translator/stm/src_stm/steal.c b/rpython/translator/stm/src_stm/steal.c --- a/rpython/translator/stm/src_stm/steal.c +++ b/rpython/translator/stm/src_stm/steal.c @@ -20,58 +20,6 @@ }; static __thread struct tx_steal_data *steal_data; -static void replace_ptr_to_immutable_with_stub(gcptr * pobj) -{ - gcptr stub, obj = *pobj; - assert(obj->h_tid & GCFLAG_IMMUTABLE); - assert(!(obj->h_tid & GCFLAG_PRIVATE_FROM_PROTECTED)); - if (obj->h_tid & GCFLAG_PUBLIC) { - /* young public, replace with stolen old copy */ - assert(obj->h_tid & GCFLAG_MOVED); - assert(IS_POINTER(obj->h_revision)); - stub = (gcptr)obj->h_revision; - assert(!IS_POINTER(stub->h_revision)); /* not outdated */ - goto done; - } - - /* old or young protected! mark as PUBLIC */ - if (!(obj->h_tid & GCFLAG_OLD)) { - /* young protected */ - gcptr O; - - if (obj->h_tid & GCFLAG_HAS_ID) { - /* use id-copy for us */ - O = (gcptr)obj->h_original; - obj->h_tid &= ~GCFLAG_HAS_ID; - stm_copy_to_old_id_copy(obj, O); - O->h_original = 0; - } else { - O = stmgc_duplicate_old(obj); - - /* young and without original? */ - if (!(obj->h_original)) - obj->h_original = (revision_t)O; - } - obj->h_tid |= (GCFLAG_MOVED | GCFLAG_PUBLIC); - obj->h_revision = (revision_t)O; - - O->h_tid |= GCFLAG_PUBLIC; - /* here it is fine if it stays in read caches because - the object is immutable anyway and there are no - write_barriers allowed. */ - dprintf(("steal prot immutable -> public: %p -> %p\n", obj, O)); - stub = O; - goto done; - } - /* old protected: */ - dprintf(("prot immutable -> public: %p\n", obj)); - obj->h_tid |= GCFLAG_PUBLIC; - - return; - done: - *pobj = stub; - dprintf((" stolen: fixing *%p: %p -> %p\n", pobj, obj, stub)); -} static void replace_ptr_to_protected_with_stub(gcptr *pobj) { @@ -80,11 +28,17 @@ (GCFLAG_PUBLIC | GCFLAG_OLD)) return; - if (obj->h_tid & GCFLAG_IMMUTABLE) { - replace_ptr_to_immutable_with_stub(pobj); - return; - } - + /* if ((obj->h_tid & GCFLAG_PUBLIC) && (obj->h_tid & GCFLAG_MOVED)) { */ + /* /\* young stolen public, replace with stolen old copy */ + /* All references in this old object should be stubbed already */ + /* by stealing.*\/ */ + /* assert(IS_POINTER(obj->h_revision)); */ + /* stub = (gcptr)obj->h_revision; */ + /* assert(stub->h_tid & GCFLAG_OLD); */ + /* assert(stub->h_tid & GCFLAG_PUBLIC); */ + /* goto done; */ + /* } */ + /* we use 'all_stubs', a dictionary, in order to try to avoid duplicate stubs for the same object. XXX maybe it would be better to use a fast approximative cache that stays around for @@ -169,6 +123,7 @@ To know which case it is, read GCFLAG_PRIVATE_FROM_PROTECTED. */ if (L->h_tid & GCFLAG_PRIVATE_FROM_PROTECTED) { + assert(!(L->h_tid & GCFLAG_IMMUTABLE)); gcptr B = (gcptr)L->h_revision; /* the backup copy */ /* On young objects here, h_original is always set @@ -298,6 +253,8 @@ memset(&sd.all_stubs, 0, sizeof(sd.all_stubs)); steal_data = &sd; stmgc_trace(L, &replace_ptr_to_protected_with_stub); + if (L->h_tid & GCFLAG_WEAKREF) + replace_ptr_to_protected_with_stub(WEAKREF_PTR(L, stmgc_size(L))); g2l_delete_not_used_any_more(&sd.all_stubs); /* If another thread (the foreign or a 3rd party) does a read diff --git a/rpython/translator/stm/src_stm/stmgc.h b/rpython/translator/stm/src_stm/stmgc.h --- a/rpython/translator/stm/src_stm/stmgc.h +++ b/rpython/translator/stm/src_stm/stmgc.h @@ -155,7 +155,7 @@ stm_inspect_abort_info(). (XXX details not documented yet) */ void stm_abort_info_push(gcptr obj, long fieldoffsets[]); void stm_abort_info_pop(long count); -char *stm_inspect_abort_info(void); +char *stm_inspect_abort_info(void); /* turns inevitable */ /* mostly for debugging support */ void stm_abort_and_retry(void); @@ -176,10 +176,14 @@ /* Clear some memory when aborting a transaction in the current thread. This is a provisional API. The information is stored - thread-locally and belongs to the current thread. */ + in the current tx_descriptor. */ void stm_clear_on_abort(void *start, size_t bytes); -extern __thread void *stm_to_clear_on_abort; -extern __thread size_t stm_bytes_to_clear_on_abort; + +/* If the current transaction aborts later, invoke 'callback(key)'. + If the current transaction commits, then the callback is forgotten. + You can only register one callback per key. You can call + 'stm_call_on_abort(key, NULL)' to cancel an existing callback. */ +void stm_call_on_abort(void *key, void callback(void *)); /* only user currently is stm_allocate_public_integer_address() */ void stm_register_integer_address(intptr_t); diff --git a/rpython/translator/stm/src_stm/stmsync.c b/rpython/translator/stm/src_stm/stmsync.c --- a/rpython/translator/stm/src_stm/stmsync.c +++ b/rpython/translator/stm/src_stm/stmsync.c @@ -69,7 +69,7 @@ assert(x == END_MARKER_ON); assert(stm_shadowstack == d->shadowstack); stm_shadowstack = NULL; - stm_free(d->shadowstack, sizeof(gcptr) * LENGTH_SHADOW_STACK); + stm_free(d->shadowstack); } void stm_set_max_aborts(int max_aborts) @@ -168,7 +168,7 @@ has configured 'reads_size_limit_nonatomic' to a smaller value. When such a shortened transaction succeeds, the next one will see its length limit doubled, up to the maximum. */ - if (counter == 0) { + if (counter == 0 && d->active != 2) { unsigned long limit = d->reads_size_limit_nonatomic; if (limit != 0 && limit < (stm_regular_length_limit >> 1)) limit = (limit << 1) | 1; @@ -219,6 +219,8 @@ struct tx_descriptor *d = thread_descriptor; if (!d->atomic) CommitTransaction(); + else + BecomeInevitable("stm_commit_transaction but atomic"); } void stm_begin_inevitable_transaction(void) diff --git a/rpython/translator/stm/src_stm/weakref.c b/rpython/translator/stm/src_stm/weakref.c --- a/rpython/translator/stm/src_stm/weakref.c +++ b/rpython/translator/stm/src_stm/weakref.c @@ -1,17 +1,16 @@ /* Imported by rpython/translator/stm/import_stmgc.py */ #include "stmimpl.h" -#define WEAKREF_PTR(wr, sz) (*(gcptr *)(((char *)(wr)) + (sz) - WORD)) - gcptr stm_weakref_allocate(size_t size, unsigned long tid, gcptr obj) { stm_push_root(obj); gcptr weakref = stm_allocate_immutable(size, tid); obj = stm_pop_root(); + weakref->h_tid |= GCFLAG_WEAKREF; assert(!(weakref->h_tid & GCFLAG_OLD)); /* 'size' too big? */ assert(stmgc_size(weakref) == size); - WEAKREF_PTR(weakref, size) = obj; + *WEAKREF_PTR(weakref, size) = obj; gcptrlist_insert(&thread_descriptor->young_weakrefs, weakref); dprintf(("alloc weakref %p -> %p\n", weakref, obj)); return weakref; @@ -32,34 +31,34 @@ continue; /* the weakref itself dies */ weakref = (gcptr)weakref->h_revision; + assert(weakref->h_tid & GCFLAG_OLD); + assert(!IS_POINTER(weakref->h_revision)); + size_t size = stmgc_size(weakref); - gcptr pointing_to = WEAKREF_PTR(weakref, size); + gcptr pointing_to = *WEAKREF_PTR(weakref, size); assert(pointing_to != NULL); if (stmgc_is_in_nursery(d, pointing_to)) { if (pointing_to->h_tid & GCFLAG_MOVED) { dprintf(("weakref ptr moved %p->%p\n", - WEAKREF_PTR(weakref, size), + *WEAKREF_PTR(weakref, size), (gcptr)pointing_to->h_revision)); - WEAKREF_PTR(weakref, size) = (gcptr)pointing_to->h_revision; + *WEAKREF_PTR(weakref, size) = (gcptr)pointing_to->h_revision; } else { - dprintf(("weakref lost ptr %p\n", WEAKREF_PTR(weakref, size))); - WEAKREF_PTR(weakref, size) = NULL; + assert(!IS_POINTER(pointing_to->h_revision)); + assert(IMPLIES(!(pointing_to->h_tid & GCFLAG_HAS_ID), + pointing_to->h_original == 0)); + + dprintf(("weakref lost ptr %p\n", *WEAKREF_PTR(weakref, size))); + *WEAKREF_PTR(weakref, size) = NULL; continue; /* no need to remember this weakref any longer */ } } - else { - /* # see test_weakref_to_prebuilt: it's not useful to put - # weakrefs into 'old_objects_with_weakrefs' if they point - # to a prebuilt object (they are immortal). If moreover - # the 'pointing_to' prebuilt object still has the - # GCFLAG_NO_HEAP_PTRS flag, then it's even wrong, because - # 'pointing_to' will not get the GCFLAG_VISITED during - # the next major collection. Solve this by not registering - # the weakref into 'old_objects_with_weakrefs'. - */ - } + assert((*WEAKREF_PTR(weakref, size))->h_tid & GCFLAG_OLD); + /* in case we now point to a stub because the weakref got stolen, + simply keep by inserting into old_weakrefs */ + gcptrlist_insert(&d->public_descriptor->old_weakrefs, weakref); } } @@ -78,11 +77,10 @@ if (obj->h_tid & GCFLAG_MARKED) return 1; - if (!(obj->h_tid & GCFLAG_PUBLIC)) - return 0; - - if (obj->h_original != 0 && - !(obj->h_tid & GCFLAG_PREBUILT_ORIGINAL)) { + /* if (!(obj->h_tid & GCFLAG_PUBLIC)) */ + /* return 0; */ + assert(!(obj->h_tid & GCFLAG_PREBUILT_ORIGINAL)); + if (obj->h_original != 0) { gcptr original = (gcptr)obj->h_original; assert(IMPLIES(original->h_tid & GCFLAG_VISITED, original->h_tid & GCFLAG_MARKED)); @@ -92,6 +90,21 @@ return 0; } +static void update_old_weakrefs_list(struct tx_public_descriptor *gcp) +{ + long i, size = gcp->old_weakrefs.size; + gcptr *items = gcp->old_weakrefs.items; + + for (i = 0; i < size; i++) { + gcptr weakref = items[i]; + + /* if a weakref moved, update its position in the list */ + if (weakref->h_tid & GCFLAG_MOVED) { + items[i] = (gcptr)weakref->h_original; + } + } +} + static void visit_old_weakrefs(struct tx_public_descriptor *gcp) { /* Note: it's possible that a weakref points to a public stub to a @@ -105,27 +118,25 @@ for (i = 0; i < size; i++) { gcptr weakref = items[i]; - /* weakrefs are immutable: during a major collection, they - cannot be in the nursery, and so there should be only one - version of each weakref object. XXX relying on this is - a bit fragile, but simplifies things a lot... */ - assert(weakref->h_revision & 1); - if (!(weakref->h_tid & GCFLAG_VISITED)) { /* the weakref itself dies */ } else { + /* the weakref belongs to our thread, therefore we should + always see the most current revision here: */ + assert(weakref->h_revision & 1); + size_t size = stmgc_size(weakref); - gcptr pointing_to = WEAKREF_PTR(weakref, size); + gcptr pointing_to = *WEAKREF_PTR(weakref, size); assert(pointing_to != NULL); if (is_partially_visited(pointing_to)) { pointing_to = stmgcpage_visit(pointing_to); dprintf(("mweakref ptr moved %p->%p\n", - WEAKREF_PTR(weakref, size), + *WEAKREF_PTR(weakref, size), pointing_to)); assert(pointing_to->h_tid & GCFLAG_VISITED); - WEAKREF_PTR(weakref, size) = pointing_to; + *WEAKREF_PTR(weakref, size) = pointing_to; } else { /* the weakref appears to be pointing to a dying object, @@ -146,12 +157,12 @@ assert(weakref->h_revision & 1); if (weakref->h_tid & GCFLAG_VISITED) { size_t size = stmgc_size(weakref); - gcptr pointing_to = WEAKREF_PTR(weakref, size); + gcptr pointing_to = *WEAKREF_PTR(weakref, size); if (pointing_to->h_tid & GCFLAG_VISITED) { continue; /* the target stays alive, the weakref remains */ } - dprintf(("mweakref lost ptr %p\n", WEAKREF_PTR(weakref, size))); - WEAKREF_PTR(weakref, size) = NULL; /* the target dies */ + dprintf(("mweakref lost ptr %p\n", *WEAKREF_PTR(weakref, size))); + *WEAKREF_PTR(weakref, size) = NULL; /* the target dies */ } /* remove this weakref from the list */ items[i] = items[--gcp->old_weakrefs.size]; @@ -171,6 +182,14 @@ visit(gcp); } +void stm_update_old_weakrefs_lists(void) +{ + /* go over old weakrefs lists and update the list with possibly + new pointers because of copy_over_original */ + for_each_public_descriptor(update_old_weakrefs_list); +} + + void stm_visit_old_weakrefs(void) { /* Figure out which weakrefs survive, which possibly diff --git a/rpython/translator/stm/src_stm/weakref.h b/rpython/translator/stm/src_stm/weakref.h --- a/rpython/translator/stm/src_stm/weakref.h +++ b/rpython/translator/stm/src_stm/weakref.h @@ -2,8 +2,10 @@ #ifndef _SRCSTM_WEAKREF_H #define _SRCSTM_WEAKREF_H +#define WEAKREF_PTR(wr, sz) ((gcptr *)(((char *)(wr)) + (sz) - WORD)) void stm_move_young_weakrefs(struct tx_descriptor *); +void stm_update_old_weakrefs_lists(void); void stm_visit_old_weakrefs(void); void stm_clean_old_weakrefs(void); From noreply at buildbot.pypy.org Sun Sep 15 12:23:22 2013 From: noreply at buildbot.pypy.org (arigo) Date: Sun, 15 Sep 2013 12:23:22 +0200 (CEST) Subject: [pypy-commit] pypy stmgc-static-barrier: hg merge stmgc-c4 Message-ID: <20130915102322.287B91C0162@cobra.cs.uni-duesseldorf.de> Author: Armin Rigo Branch: stmgc-static-barrier Changeset: r66951:4026dcfbe1ef Date: 2013-09-15 10:35 +0200 http://bitbucket.org/pypy/pypy/changeset/4026dcfbe1ef/ Log: hg merge stmgc-c4 diff too long, truncating to 2000 out of 87241 lines diff --git a/LICENSE b/LICENSE --- a/LICENSE +++ b/LICENSE @@ -2,9 +2,9 @@ ======= Except when otherwise stated (look for LICENSE files in directories or -information at the beginning of each file) all software and -documentation in the 'pypy', 'ctype_configure', 'dotviewer', 'demo', -and 'lib_pypy' directories is licensed as follows: +information at the beginning of each file) all software and documentation in +the 'rpython', 'pypy', 'ctype_configure', 'dotviewer', 'demo', and 'lib_pypy' +directories is licensed as follows: The MIT License @@ -38,176 +38,239 @@ Armin Rigo Maciej Fijalkowski Carl Friedrich Bolz + Antonio Cuni Amaury Forgeot d'Arc - Antonio Cuni Samuele Pedroni + Alex Gaynor Michael Hudson + David Schneider Holger Krekel - Alex Gaynor Christian Tismer Hakan Ardo Benjamin Peterson - David Schneider + Matti Picus + Philip Jenvey + Anders Chrigstrom + Brian Kearns Eric van Riet Paap - Anders Chrigstrom Richard Emslie + Alexander Schremmer + Wim Lavrijsen Dan Villiom Podlaski Christiansen - Alexander Schremmer + Manuel Jacob Lukas Diekmann + Sven Hager + Anders Lehmann Aurelien Campeas - Anders Lehmann + Niklaus Haldimann + Ronan Lamy Camillo Bruni - Niklaus Haldimann - Sven Hager + Laura Creighton + Toon Verwaest Leonardo Santagada - Toon Verwaest Seo Sanghyeon Justin Peel + Ronny Pfannschmidt + David Edelsohn + Anders Hammarquist + Jakub Gustak + Guido Wesdorp Lawrence Oluyede Bartosz Skowron - Jakub Gustak - Guido Wesdorp Daniel Roberts - Laura Creighton + Niko Matsakis Adrien Di Mascio Ludovic Aubry - Niko Matsakis - Wim Lavrijsen - Matti Picus + Alexander Hesse + Jacob Hallen + Romain Guillebert Jason Creighton - Jacob Hallen Alex Martelli - Anders Hammarquist + Michal Bendowski Jan de Mooij + Michael Foord Stephan Diehl - Michael Foord Stefan Schwarzer + Valentino Volonghi Tomek Meka Patrick Maupin + stian Bob Ippolito Bruno Gola + Jean-Paul Calderone + Timo Paulssen Alexandre Fayolle + Simon Burton Marius Gedminas - Simon Burton - David Edelsohn - Jean-Paul Calderone John Witulski - Timo Paulssen - holger krekel + Greg Price Dario Bertini Mark Pearse + Simon Cross + Konstantin Lopuhin Andreas Stührk Jean-Philippe St. Pierre Guido van Rossum Pavel Vinogradov - Valentino Volonghi Paul deGrandis Ilya Osadchiy - Ronny Pfannschmidt Adrian Kuhn + Boris Feigin tav Georg Brandl - Philip Jenvey + Bert Freudenberg + Stian Andreassen + Stefano Rivera + Wanja Saatkamp Gerald Klix - Wanja Saatkamp - Boris Feigin + Mike Blume + Taavi Burns Oscar Nierstrasz David Malcolm Eugene Oden Henry Mason + Preston Timmons Jeff Terrace + David Ripton + Dusty Phillips Lukas Renggli Guenter Jantzen + Tobias Oberstein + Remi Meier Ned Batchelder - Bert Freudenberg Amit Regmi Ben Young Nicolas Chauvat Andrew Durdin Michael Schneider Nicholas Riley + Jason Chu + Igor Trindade Oliveira + Jeremy Thurgood Rocco Moretti Gintautas Miliauskas Michael Twomey - Igor Trindade Oliveira Lucian Branescu Mihaila + Tim Felgentreff + Tyler Wade + Gabriel Lavoie Olivier Dormond Jared Grubb Karl Bartel - Gabriel Lavoie + Brian Dorsey Victor Stinner - Brian Dorsey Stuart Williams + Jasper Schulz Toby Watson Antoine Pitrou + Aaron Iles + Michael Cheng Justas Sadzevicius + Gasper Zejn Neil Shepperd Mikael Schönenberg - Gasper Zejn + Elmo Mäntynen + Tobias Pape Jonathan David Riehl - Elmo Mäntynen + Stanislaw Halik Anders Qvist + Chirag Jadwani Beatrice During + Alex Perry + Vincent Legoll + Alan McIntyre Alexander Sedov Corbin Simpson - Vincent Legoll - Romain Guillebert - Alan McIntyre - Alex Perry + Christopher Pope + Laurence Tratt + Guillebert Romain + Christian Tismer + Dan Stromberg + Stefano Parmesan + Christian Hudon + Alexis Daboville Jens-Uwe Mager - Simon Cross - Dan Stromberg - Guillebert Romain Carl Meyer + Karl Ramm Pieter Zieschang + Gabriel + Paweł Piotr Przeradowski + Andrew Dalke + Sylvain Thenault + Nathan Taylor + Vladimir Kryachko + Jacek Generowicz Alejandro J. Cura - Sylvain Thenault - Christoph Gerum + Jacob Oscarson Travis Francis Athougies + Kristjan Valur Jonsson + Neil Blakey-Milner + Lutz Paelike + Lucio Torre + Lars Wassermann Henrik Vendelbo - Lutz Paelike - Jacob Oscarson - Martin Blais - Lucio Torre - Lene Wagner + Dan Buch Miguel de Val Borro Artur Lisiecki - Bruno Gola + Sergey Kishchenko Ignas Mikalajunas - Stefano Rivera + Christoph Gerum + Martin Blais + Lene Wagner + Tomo Cocoa + Andrews Medina + roberto at goyle + William Leslie + Bobby Impollonia + timo at eistee.fritz.box + Andrew Thompson + Yusei Tahara + Roberto De Ioris + Juan Francisco Cantero Hurtado + Godefroid Chappelle Joshua Gilbert - Godefroid Chappelle - Yusei Tahara + Dan Colish Christopher Armstrong + Michael Hudson-Doyle + Anders Sigfridsson + Yasir Suhail + Floris Bruynooghe + Akira Li + Gustavo Niemeyer Stephan Busemann - Gustavo Niemeyer - William Leslie - Akira Li - Kristjan Valur Jonsson - Bobby Impollonia - Michael Hudson-Doyle - Laurence Tratt - Yasir Suhail - Andrew Thompson - Anders Sigfridsson - Floris Bruynooghe - Jacek Generowicz - Dan Colish - Zooko Wilcox-O Hearn - Dan Loewenherz + Anna Katrina Dominguez + Christian Muirhead + James Lan + shoma hosaka + Daniel Neuhäuser + Buck Golemon + Konrad Delong + Dinu Gherman Chris Lambacher - Dinu Gherman - Brett Cannon - Daniel Neuhäuser - Michael Chermside - Konrad Delong - Anna Ravencroft - Greg Price - Armin Ronacher - Christian Muirhead + coolbutuseless at gmail.com Jim Baker Rodrigo Araújo - Romain Guillebert + Armin Ronacher + Brett Cannon + yrttyr + Zooko Wilcox-O Hearn + Tomer Chachamu + Christopher Groskopf + opassembler.py + Antony Lee + Jim Hunziker + Markus Unterwaditzer + Even Wiik Thomassen + jbs + soareschen + Flavio Percoco + Kristoffer Kleine + yasirs + Michael Chermside + Anna Ravencroft + Andrew Chambers + Julien Phalip + Dan Loewenherz Heinrich-Heine University, Germany Open End AB (formerly AB Strakt), Sweden @@ -219,45 +282,21 @@ Change Maker, Sweden University of California Berkeley, USA Google Inc. + King's College London The PyPy Logo as used by http://speed.pypy.org and others was created by Samuel Reis and is distributed on terms of Creative Commons Share Alike License. -License for 'lib-python/2.7.0' and 'lib-python/2.7.0-modified' -============================================================== +License for 'lib-python/2.7' +============================ -Except when otherwise stated (look for LICENSE files or -copyright/license information at the beginning of each file) the files -in the 'lib-python/2.7.0' and 'lib-python/2.7.0-modified' directories -are all copyrighted by the Python Software Foundation and licensed under -the Python Software License of which you can find a copy here: +Except when otherwise stated (look for LICENSE files or copyright/license +information at the beginning of each file) the files in the 'lib-python/2.7' +directory are all copyrighted by the Python Software Foundation and licensed +under the Python Software License of which you can find a copy here: http://www.python.org/doc/Copyright.html -License for 'pypy/translator/jvm/src/jna.jar' -============================================= - -The file 'pypy/translator/jvm/src/jna.jar' is licensed under the GNU -Lesser General Public License of which you can find a copy here: -http://www.gnu.org/licenses/lgpl.html - -License for 'pypy/translator/jvm/src/jasmin.jar' -================================================ - -The file 'pypy/translator/jvm/src/jasmin.jar' is copyright (c) 1996-2004 Jon Meyer -and distributed with permission. The use of Jasmin by PyPy does not imply -that PyPy is endorsed by Jon Meyer nor any of Jasmin's contributors. Furthermore, -the following disclaimer applies to Jasmin: - -THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED -WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A -PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR -ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT -LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS -INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR -TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF -ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - License for 'pypy/module/unicodedata/' ====================================== diff --git a/dotviewer/drawgraph.py b/dotviewer/drawgraph.py --- a/dotviewer/drawgraph.py +++ b/dotviewer/drawgraph.py @@ -22,6 +22,7 @@ 'yellow': (255,255,0), } re_nonword=re.compile(r'([^0-9a-zA-Z_.]+)') +re_linewidth=re.compile(r'setlinewidth\((\d+(\.\d*)?|\.\d+)\)') def combine(color1, color2, alpha): r1, g1, b1 = color1 @@ -138,6 +139,13 @@ self.yl = float(yl) rest = rest[3:] self.style, self.color = rest + linematch = re_linewidth.match(self.style) + if linematch: + num = linematch.group(1) + self.linewidth = int(round(float(num))) + self.style = self.style[linematch.end(0):] + else: + self.linewidth = 1 self.highlight = False self.cachedbezierpoints = None self.cachedarrowhead = None @@ -520,8 +528,8 @@ fgcolor = highlight_color(fgcolor) points = [self.map(*xy) for xy in edge.bezierpoints()] - def drawedgebody(points=points, fgcolor=fgcolor): - pygame.draw.lines(self.screen, fgcolor, False, points) + def drawedgebody(points=points, fgcolor=fgcolor, width=edge.linewidth): + pygame.draw.lines(self.screen, fgcolor, False, points, width) edgebodycmd.append(drawedgebody) points = [self.map(*xy) for xy in edge.arrowhead()] diff --git a/dotviewer/graphparse.py b/dotviewer/graphparse.py --- a/dotviewer/graphparse.py +++ b/dotviewer/graphparse.py @@ -152,7 +152,8 @@ try: plaincontent = dot2plain_graphviz(content, contenttype) except PlainParseError, e: - print e - # failed, retry via codespeak - plaincontent = dot2plain_codespeak(content, contenttype) + raise + ##print e + ### failed, retry via codespeak + ##plaincontent = dot2plain_codespeak(content, contenttype) return list(parse_plain(graph_id, plaincontent, links, fixedfont)) diff --git a/dotviewer/test/test_interactive.py b/dotviewer/test/test_interactive.py --- a/dotviewer/test/test_interactive.py +++ b/dotviewer/test/test_interactive.py @@ -34,6 +34,23 @@ } ''' +SOURCE2=r'''digraph f { + a; d; e; f; g; h; i; j; k; l; + a -> d [penwidth=1, style="setlinewidth(1)"]; + d -> e [penwidth=2, style="setlinewidth(2)"]; + e -> f [penwidth=4, style="setlinewidth(4)"]; + f -> g [penwidth=8, style="setlinewidth(8)"]; + g -> h [penwidth=16, style="setlinewidth(16)"]; + h -> i [penwidth=32, style="setlinewidth(32)"]; + i -> j [penwidth=64, style="setlinewidth(64)"]; + j -> k [penwidth=128, style="setlinewidth(128)"]; + k -> l [penwidth=256, style="setlinewidth(256)"]; +}''' + + + + + def setup_module(mod): if not option.pygame: py.test.skip("--pygame not enabled") @@ -161,3 +178,10 @@ page = MyPage(str(dotfile)) page.fixedfont = True graphclient.display_page(page) + +def test_linewidth(): + udir.join("graph2.dot").write(SOURCE2) + from dotviewer import graphpage, graphclient + dotfile = udir.join('graph2.dot') + page = graphpage.DotFileGraphPage(str(dotfile)) + graphclient.display_page(page) diff --git a/lib-python/2.7/argparse.py b/lib-python/2.7/argparse.py --- a/lib-python/2.7/argparse.py +++ b/lib-python/2.7/argparse.py @@ -1780,7 +1780,19 @@ # error if this argument is not allowed with other previously # seen arguments, assuming that actions that use the default # value don't really count as "present" - if argument_values is not action.default: + + # XXX PyPy bug-to-bug compatibility: "is" on primitive types + # is not consistent in CPython. We'll assume it is close + # enough for ints (which is true only for "small ints"), but + # for floats and longs and complexes we'll go for the option + # of forcing "is" to say False, like it usually does on + # CPython. A fix is pending on CPython trunk + # (http://bugs.python.org/issue18943) but that might change + # the details of the semantics and so not be applied to 2.7. + # See the line AA below. + + if (argument_values is not action.default or + type(argument_values) in (float, long, complex)): # AA seen_non_default_actions.add(action) for conflict_action in action_conflicts.get(action, []): if conflict_action in seen_non_default_actions: diff --git a/lib-python/2.7/distutils/sysconfig_pypy.py b/lib-python/2.7/distutils/sysconfig_pypy.py --- a/lib-python/2.7/distutils/sysconfig_pypy.py +++ b/lib-python/2.7/distutils/sysconfig_pypy.py @@ -12,6 +12,7 @@ import sys import os +import shlex from distutils.errors import DistutilsPlatformError @@ -124,11 +125,19 @@ if compiler.compiler_type == "unix": compiler.compiler_so.extend(['-O2', '-fPIC', '-Wimplicit']) compiler.shared_lib_extension = get_config_var('SO') + if "CPPFLAGS" in os.environ: + cppflags = shlex.split(os.environ["CPPFLAGS"]) + compiler.compiler.extend(cppflags) + compiler.compiler_so.extend(cppflags) + compiler.linker_so.extend(cppflags) if "CFLAGS" in os.environ: - cflags = os.environ["CFLAGS"].split() + cflags = shlex.split(os.environ["CFLAGS"]) compiler.compiler.extend(cflags) compiler.compiler_so.extend(cflags) compiler.linker_so.extend(cflags) + if "LDFLAGS" in os.environ: + ldflags = shlex.split(os.environ["LDFLAGS"]) + compiler.linker_so.extend(ldflags) from sysconfig_cpython import ( diff --git a/lib-python/2.7/json/__init__.py b/lib-python/2.7/json/__init__.py --- a/lib-python/2.7/json/__init__.py +++ b/lib-python/2.7/json/__init__.py @@ -105,6 +105,12 @@ __author__ = 'Bob Ippolito ' +try: + # PyPy speedup, the interface is different than CPython's _json + import _pypyjson +except ImportError: + _pypyjson = None + from .decoder import JSONDecoder from .encoder import JSONEncoder @@ -241,7 +247,6 @@ _default_decoder = JSONDecoder(encoding=None, object_hook=None, object_pairs_hook=None) - def load(fp, encoding=None, cls=None, object_hook=None, parse_float=None, parse_int=None, parse_constant=None, object_pairs_hook=None, **kw): """Deserialize ``fp`` (a ``.read()``-supporting file-like object containing @@ -323,7 +328,10 @@ if (cls is None and encoding is None and object_hook is None and parse_int is None and parse_float is None and parse_constant is None and object_pairs_hook is None and not kw): - return _default_decoder.decode(s) + if _pypyjson and not isinstance(s, unicode): + return _pypyjson.loads(s) + else: + return _default_decoder.decode(s) if cls is None: cls = JSONDecoder if object_hook is not None: diff --git a/lib-python/2.7/socket.py b/lib-python/2.7/socket.py --- a/lib-python/2.7/socket.py +++ b/lib-python/2.7/socket.py @@ -165,6 +165,8 @@ # All _delegate_methods must also be initialized here. send = recv = recv_into = sendto = recvfrom = recvfrom_into = _dummy __getattr__ = _dummy + def _drop(self): + pass # Wrapper around platform socket objects. This implements # a platform-independent dup() functionality. The @@ -179,12 +181,21 @@ def __init__(self, family=AF_INET, type=SOCK_STREAM, proto=0, _sock=None): if _sock is None: _sock = _realsocket(family, type, proto) - elif _type(_sock) is _realsocket: + else: + # PyPy note about refcounting: implemented with _reuse()/_drop() + # on the class '_socket.socket'. Python 3 did it differently + # with a reference counter on this class 'socket._socketobject' + # instead, but it is a less compatible change. + + # Note that a few libraries (like eventlet) poke at the + # private implementation of socket.py, passing custom + # objects to _socketobject(). These libraries need the + # following fix for use on PyPy: the custom objects need + # methods _reuse() and _drop() that maintains an explicit + # reference counter, starting at 0. When it drops back to + # zero, close() must be called. _sock._reuse() - # PyPy note about refcounting: implemented with _reuse()/_drop() - # on the class '_socket.socket'. Python 3 did it differently - # with a reference counter on this class 'socket._socketobject' - # instead, but it is a less compatible change (breaks eventlet). + self._sock = _sock def send(self, data, flags=0): @@ -216,9 +227,8 @@ def close(self): s = self._sock - if type(s) is _realsocket: - s._drop() self._sock = _closedsocket() + s._drop() close.__doc__ = _realsocket.close.__doc__ def accept(self): @@ -280,8 +290,14 @@ "_close"] def __init__(self, sock, mode='rb', bufsize=-1, close=False): - if type(sock) is _realsocket: - sock._reuse() + # Note that a few libraries (like eventlet) poke at the + # private implementation of socket.py, passing custom + # objects to _fileobject(). These libraries need the + # following fix for use on PyPy: the custom objects need + # methods _reuse() and _drop() that maintains an explicit + # reference counter, starting at 0. When it drops back to + # zero, close() must be called. + sock._reuse() self._sock = sock self.mode = mode # Not actually used in this version if bufsize < 0: @@ -317,11 +333,11 @@ self.flush() finally: s = self._sock - if type(s) is _realsocket: + self._sock = None + if s is not None: s._drop() - if self._close: - self._sock.close() - self._sock = None + if self._close: + s.close() def __del__(self): try: diff --git a/lib-python/2.7/ssl.py b/lib-python/2.7/ssl.py --- a/lib-python/2.7/ssl.py +++ b/lib-python/2.7/ssl.py @@ -110,6 +110,12 @@ suppress_ragged_eofs=True, ciphers=None): socket.__init__(self, _sock=sock._sock) + # "close" the original socket: it is not usable any more. + # this only calls _drop(), which should not actually call + # the operating system's close() because the reference + # counter is greater than 1 (we hold one too). + sock.close() + if ciphers is None and ssl_version != _SSLv2_IF_EXISTS: ciphers = _DEFAULT_CIPHERS @@ -352,11 +358,19 @@ works with the SSL connection. Just use the code from the socket module.""" - self._makefile_refs += 1 # close=True so as to decrement the reference count when done with # the file-like object. return _fileobject(self, mode, bufsize, close=True) + def _reuse(self): + self._makefile_refs += 1 + + def _drop(self): + if self._makefile_refs < 1: + self.close() + else: + self._makefile_refs -= 1 + def wrap_socket(sock, keyfile=None, certfile=None, diff --git a/lib-python/2.7/test/test_os.py b/lib-python/2.7/test/test_os.py --- a/lib-python/2.7/test/test_os.py +++ b/lib-python/2.7/test/test_os.py @@ -275,7 +275,7 @@ try: result.f_bfree = 1 self.fail("No exception thrown") - except TypeError: + except (TypeError, AttributeError): pass try: diff --git a/lib-python/2.7/test/test_socket.py b/lib-python/2.7/test/test_socket.py --- a/lib-python/2.7/test/test_socket.py +++ b/lib-python/2.7/test/test_socket.py @@ -1066,6 +1066,9 @@ def recv(self, size): return self._recv_step.next()() + def _reuse(self): pass + def _drop(self): pass + @staticmethod def _raise_eintr(): raise socket.error(errno.EINTR) @@ -1321,7 +1324,8 @@ closed = False def flush(self): pass def close(self): self.closed = True - def _decref_socketios(self): pass + def _reuse(self): pass + def _drop(self): pass # must not close unless we request it: the original use of _fileobject # by module socket requires that the underlying socket not be closed until diff --git a/lib-python/2.7/test/test_urllib2.py b/lib-python/2.7/test/test_urllib2.py --- a/lib-python/2.7/test/test_urllib2.py +++ b/lib-python/2.7/test/test_urllib2.py @@ -270,6 +270,8 @@ self.reason = reason def read(self): return '' + def _reuse(self): pass + def _drop(self): pass class MockHTTPClass: def __init__(self): diff --git a/lib-python/2.7/urllib2.py b/lib-python/2.7/urllib2.py --- a/lib-python/2.7/urllib2.py +++ b/lib-python/2.7/urllib2.py @@ -1193,6 +1193,8 @@ # out of socket._fileobject() and into a base class. r.recv = r.read + r._reuse = lambda: None + r._drop = lambda: None fp = socket._fileobject(r, close=True) resp = addinfourl(fp, r.msg, req.get_full_url()) diff --git a/lib-python/2.7/uuid.py b/lib-python/2.7/uuid.py --- a/lib-python/2.7/uuid.py +++ b/lib-python/2.7/uuid.py @@ -44,6 +44,8 @@ UUID('00010203-0405-0607-0809-0a0b0c0d0e0f') """ +import struct + __author__ = 'Ka-Ping Yee ' RESERVED_NCS, RFC_4122, RESERVED_MICROSOFT, RESERVED_FUTURE = [ @@ -125,25 +127,38 @@ overriding the given 'hex', 'bytes', 'bytes_le', 'fields', or 'int'. """ - if [hex, bytes, bytes_le, fields, int].count(None) != 4: - raise TypeError('need one of hex, bytes, bytes_le, fields, or int') if hex is not None: + if (bytes is not None or bytes_le is not None or fields is not None + or int is not None): + raise TypeError('if the hex argument is given, bytes, bytes_le, fields,' + ' and int need to be None') hex = hex.replace('urn:', '').replace('uuid:', '') hex = hex.strip('{}').replace('-', '') if len(hex) != 32: raise ValueError('badly formed hexadecimal UUID string') int = long(hex, 16) - if bytes_le is not None: + elif bytes_le is not None: + if bytes is not None or fields is not None or int is not None: + raise TypeError('if the bytes_le argument is given, bytes, fields,' + ' and int need to be None') if len(bytes_le) != 16: raise ValueError('bytes_le is not a 16-char string') bytes = (bytes_le[3] + bytes_le[2] + bytes_le[1] + bytes_le[0] + bytes_le[5] + bytes_le[4] + bytes_le[7] + bytes_le[6] + bytes_le[8:]) - if bytes is not None: + int = (struct.unpack('>Q', bytes[:8])[0] << 64 | + struct.unpack('>Q', bytes[8:])[0]) + elif bytes is not None: + if fields is not None or int is not None: + raise TypeError('if the bytes argument is given, fields' + ' and int need to be None') if len(bytes) != 16: raise ValueError('bytes is not a 16-char string') - int = long(('%02x'*16) % tuple(map(ord, bytes)), 16) - if fields is not None: + int = (struct.unpack('>Q', bytes[:8])[0] << 64 | + struct.unpack('>Q', bytes[8:])[0]) + elif fields is not None: + if int is not None: + raise TypeError('if the fields argument is given, int needs to be None') if len(fields) != 6: raise ValueError('fields is not a 6-tuple') (time_low, time_mid, time_hi_version, @@ -163,9 +178,12 @@ clock_seq = (clock_seq_hi_variant << 8L) | clock_seq_low int = ((time_low << 96L) | (time_mid << 80L) | (time_hi_version << 64L) | (clock_seq << 48L) | node) - if int is not None: + elif int is not None: if not 0 <= int < 1<<128L: raise ValueError('int is out of range (need a 128-bit value)') + else: + raise TypeError('one of hex, bytes, bytes_le, fields,' + ' or int need to be not None') if version is not None: if not 1 <= version <= 5: raise ValueError('illegal version number') @@ -175,7 +193,7 @@ # Set the version number. int &= ~(0xf000 << 64L) int |= version << 76L - self.__dict__['int'] = int + object.__setattr__(self, 'int', int) def __cmp__(self, other): if isinstance(other, UUID): diff --git a/lib_pypy/_curses.py b/lib_pypy/_curses.py --- a/lib_pypy/_curses.py +++ b/lib_pypy/_curses.py @@ -1,6 +1,9 @@ """Reimplementation of the standard extension module '_curses' using cffi.""" import sys +if sys.platform == 'win32': + #This module does not exist in windows + raise ImportError('No module named _curses') from functools import wraps from cffi import FFI @@ -966,7 +969,7 @@ r, g, b = ffi.new("short *"), ffi.new("short *"), ffi.new("short *") if lib.color_content(color, r, g, b) == lib.ERR: raise error("Argument 1 was out of range. Check value of COLORS.") - return (r, g, b) + return (r[0], g[0], b[0]) def color_pair(n): @@ -1121,6 +1124,7 @@ term = ffi.NULL err = ffi.new("int *") if lib.setupterm(term, fd, err) == lib.ERR: + err = err[0] if err == 0: raise error("setupterm: could not find terminal") elif err == -1: diff --git a/lib_pypy/_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 @@ -165,6 +165,63 @@ Nyy rkprcgoybpxf frrz fnar. N cvax tyvggrel ebgngvat ynzoqn "vg'f yvxryl grzcbenel hagvy sberire" nevtb +"Lbh xabj jung'f avpr nobhg EClguba? Ybatre fjbeq svtugf." +nccneragyl pbashfvba vf n srngher +nccneragyl pbashfvba vf n srngher... be vf vg? +ClCl 1.7 eryrnfrq +vs lbh jnag gb or penml, lbh qba'g unir gb sbepr vg +vs lbh jnag vg gb or iveghny, lbh fubhyq abg sbepr vg + svwny: V whfg... fgnegrq pbqvat naq fhqqragyl... nobzvangvba +fabj, fabj! :-) +fabj, fabj, fabj, fabj +clcl 1.8 eryrnfrq +vg jnf srj lnxf gbb yngr +ClCl vf n enpr orgjrra hf funivat lnxf, naq gur havirefr gelvat gb cebqhpr zber naq zber lnxf +Jevgvat na SC7 nabalzbhf cebcbfny sbe ClCl vf yvxr znxvat n gi nq sbe n uvtu cresbeznapr fcbegf pne jvgubhg orvat noyr gb zragvba vgf zbqry be znahsnpghere +Fabj, fabj (ntnva) +Fgvyy fabjvat +thrff jung, fabj +"lbh haqrerfgvzngr gur vzcbegnapr bs zvpebnepuvgrpgher" "ab, vg'f zber gung jr ner fgvyy unccvyl va gur ynaq bs ernpunoyr sehvg" +Jub nz V? Naq vs lrf, ubj znal? +ClCl vf nyjnlf n cynfzn +"genafyngvba gbbypunva" = "EClgure"? gb jevgr vagrEClguref va +"sberire" va clcl grezf zrnaf yvxr srj zbaguf :) +"Onu. PClguba bofphevgl. - Nezva Evtb" +svwny: pna V vavgvngr lbh ba gur (rnfl ohg) aba-gevivny gbcvp bs jevgvat P shapgvba glcrf? :-) +nyy fbsgjner vzcebirzragf unccra ol n ovg +gur genprf qba'g yvr +:-) be engure ":-/" bss-ol-bar-xrl reebe +Be Nezva Evtb. V guvax ur'f noyr gb haqrefgnaq k86 gur jnl Plcure pna frr jbzra va gur zngevk. +V zvtug, ohg abobql erfcrpgf zr +cerohvyg vafgnapr Ryyvcfvf unf ab nggevohgr 'reeab' +guvf frnfba'f svefg "fabj! fabj!" vf urer +ClCl 2.0 orgn1 eryrnfrq - orggre yngr guna arire +Fjvgreynaq 2012: zber fabj va Qrprzore guna rire fvapr clcl fgnegrq +Fjvgmreynaq 2012: zber fabj va Qrprzore guna rire fvapr clcl fgnegrq + n sngny reebe, ol qrsvavgvba, vf sngny + V'z tynq gung jr cebtenz va Clguba naq jr qba'g qrny jvgu gubfr vffhrf rirel qnl. Ncneg gur snpg gung jr unir gb qrny jvgu gurz naljnl, vg frrzf +unccl arj lrne! +"zrffl" vf abg n whqtrzrag, ohg whfg n snpg bs pbzcyvpngrqarff +n ybg bs fabj +qb lbh xabj nobhg n gbnfgre jvgu 8XO bs ENZ naq 64XO bs EBZ? +vg'f orra fabjvat rirelqnl sbe n juvyr, V pna'g whfg chg "fabj, fabj" hc urer rirel qnl +fabjonyy svtugf! +sbejneq pbzcngvovyvgl jvgu bcgvzvmngvbaf gung unira'g orra vairagrq lrg +jr fgvyy unir gb jevgr fbsgjner jvgu n zrgnfcnpr ohooyr va vg +cebonoyl gur ynfg gvzr va gur frnfba, ohg: fabj, fabj! +ClCl 2.0-orgn2 eryrnfrq +Gur ceboyrz vf gung sbe nyzbfg nal aba-gevivny cebtenz, vg'f abg pyrne jung 'pbeerpg' zrnaf. +ClCl 2.0 nyzbfg eryrnfrq +ClCl 2.0 eryrnfrq +WVG pbzcvyref fubhyq or jevggra ol crbcyr jub npghnyyl unir snvgu va WVG pbzcvyref' novyvgl gb znxrf guvatf tb fpernzvat snfg +ClCl 2.0.1 eryrnfrq +arire haqrerfgvzngr gur vzcebonoyr jura lbh qb fbzrguvat ng 2TUm +ClCl 2.0.2 eryrnfrq +nyy jr arrq vf n angvir Cebybt znpuvar +V haqrefgnaq ubj qravnyvfz vf n onq qrohttvat grpuavdhr +rirel IZ fubhyq pbzr jvgu arheny argjbex genvarq gb erpbtavmr zvpeborapuznexf naq enaqbzyl syhpghngr gurz +/-9000% +lbh qvq abg nccebnpu clcl sebz gur rnfl raq: fgz, gura wvg. vg'f n ovg gur Abegu snpr +va ClCl orvat bayl zbqrengryl zntvp vf n tbbq guvat """ from string import ascii_uppercase, ascii_lowercase diff --git a/lib_pypy/_sqlite3.py b/lib_pypy/_sqlite3.py --- a/lib_pypy/_sqlite3.py +++ b/lib_pypy/_sqlite3.py @@ -1229,7 +1229,10 @@ if cvt is not None: param = cvt(param) - param = adapt(param) + try: + param = adapt(param) + except: + pass # And use previous value if param is None: rc = _lib.sqlite3_bind_null(self._statement, idx) @@ -1305,7 +1308,7 @@ for i in xrange(_lib.sqlite3_column_count(self._statement)): name = _lib.sqlite3_column_name(self._statement, i) if name: - name = _ffi.string(name).decode('utf-8').split("[")[0].strip() + name = _ffi.string(name).split("[")[0].strip() desc.append((name, None, None, None, None, None, None)) return desc diff --git a/lib_pypy/_tkinter/__init__.py b/lib_pypy/_tkinter/__init__.py --- a/lib_pypy/_tkinter/__init__.py +++ b/lib_pypy/_tkinter/__init__.py @@ -22,6 +22,7 @@ READABLE = tklib.TCL_READABLE WRITABLE = tklib.TCL_WRITABLE EXCEPTION = tklib.TCL_EXCEPTION +DONT_WAIT = tklib.TCL_DONT_WAIT def create(screenName=None, baseName=None, className=None, interactive=False, wantobjects=False, wantTk=True, diff --git a/lib_pypy/_tkinter/app.py b/lib_pypy/_tkinter/app.py --- a/lib_pypy/_tkinter/app.py +++ b/lib_pypy/_tkinter/app.py @@ -4,7 +4,23 @@ from . import TclError from .tclobj import TclObject, FromObj, AsObj, TypeCache +import contextlib import sys +import threading +import time + + +class _DummyLock(object): + "A lock-like object that does not do anything" + def acquire(self): + pass + def release(self): + pass + def __enter__(self): + pass + def __exit__(self, *exc): + pass + def varname_converter(input): if isinstance(input, TclObject): @@ -37,17 +53,18 @@ def PythonCmd(clientData, interp, argc, argv): self = tkffi.from_handle(clientData) assert self.app.interp == interp - try: - args = [tkffi.string(arg) for arg in argv[1:argc]] - result = self.func(*args) - obj = AsObj(result) - tklib.Tcl_SetObjResult(interp, obj) - except: - self.app.errorInCmd = True - self.app.exc_info = sys.exc_info() - return tklib.TCL_ERROR - else: - return tklib.TCL_OK + with self.app._tcl_lock_released(): + try: + args = [tkffi.string(arg) for arg in argv[1:argc]] + result = self.func(*args) + obj = AsObj(result) + tklib.Tcl_SetObjResult(interp, obj) + except: + self.app.errorInCmd = True + self.app.exc_info = sys.exc_info() + return tklib.TCL_ERROR + else: + return tklib.TCL_OK @tkffi.callback("Tcl_CmdDeleteProc") def PythonCmdDelete(clientData): @@ -58,6 +75,8 @@ class TkApp(object): + _busywaitinterval = 0.02 # 20ms. + def __new__(cls, screenName, baseName, className, interactive, wantobjects, wantTk, sync, use): if not wantobjects: @@ -73,6 +92,12 @@ self.quitMainLoop = False self.errorInCmd = False + if not self.threaded: + # TCL is not thread-safe, calls needs to be serialized. + self._tcl_lock = threading.Lock() + else: + self._tcl_lock = _DummyLock() + self._typeCache = TypeCache() self._commands = {} @@ -133,6 +158,13 @@ if self.threaded and self.thread_id != tklib.Tcl_GetCurrentThread(): raise RuntimeError("Calling Tcl from different appartment") + @contextlib.contextmanager + def _tcl_lock_released(self): + "Context manager to temporarily release the tcl lock." + self._tcl_lock.release() + yield + self._tcl_lock.acquire() + def loadtk(self): # We want to guard against calling Tk_Init() multiple times err = tklib.Tcl_Eval(self.interp, "info exists tk_version") @@ -159,22 +191,25 @@ flags=tklib.TCL_LEAVE_ERR_MSG if global_only: flags |= tklib.TCL_GLOBAL_ONLY - res = tklib.Tcl_GetVar2Ex(self.interp, name1, name2, flags) - if not res: - self.raiseTclError() - assert self._wantobjects - return FromObj(self, res) + with self._tcl_lock: + res = tklib.Tcl_GetVar2Ex(self.interp, name1, name2, flags) + if not res: + self.raiseTclError() + assert self._wantobjects + return FromObj(self, res) def _setvar(self, name1, value, global_only=False): name1 = varname_converter(name1) + # XXX Acquire tcl lock??? newval = AsObj(value) flags=tklib.TCL_LEAVE_ERR_MSG if global_only: flags |= tklib.TCL_GLOBAL_ONLY - res = tklib.Tcl_SetVar2Ex(self.interp, name1, tkffi.NULL, - newval, flags) - if not res: - self.raiseTclError() + with self._tcl_lock: + res = tklib.Tcl_SetVar2Ex(self.interp, name1, tkffi.NULL, + newval, flags) + if not res: + self.raiseTclError() def _unsetvar(self, name1, name2=None, global_only=False): name1 = varname_converter(name1) @@ -183,9 +218,10 @@ flags=tklib.TCL_LEAVE_ERR_MSG if global_only: flags |= tklib.TCL_GLOBAL_ONLY - res = tklib.Tcl_UnsetVar2(self.interp, name1, name2, flags) - if res == tklib.TCL_ERROR: - self.raiseTclError() + with self._tcl_lock: + res = tklib.Tcl_UnsetVar2(self.interp, name1, name2, flags) + if res == tklib.TCL_ERROR: + self.raiseTclError() def getvar(self, name1, name2=None): return self._var_invoke(self._getvar, name1, name2) @@ -219,9 +255,10 @@ if self.threaded and self.thread_id != tklib.Tcl_GetCurrentThread(): raise NotImplementedError("Call from another thread") - res = tklib.Tcl_CreateCommand( - self.interp, cmdName, _CommandData.PythonCmd, - clientData, _CommandData.PythonCmdDelete) + with self._tcl_lock: + res = tklib.Tcl_CreateCommand( + self.interp, cmdName, _CommandData.PythonCmd, + clientData, _CommandData.PythonCmdDelete) if not res: raise TclError("can't create Tcl command") @@ -229,7 +266,8 @@ if self.threaded and self.thread_id != tklib.Tcl_GetCurrentThread(): raise NotImplementedError("Call from another thread") - res = tklib.Tcl_DeleteCommand(self.interp, cmdName) + with self._tcl_lock: + res = tklib.Tcl_DeleteCommand(self.interp, cmdName) if res == -1: raise TclError("can't delete Tcl command") @@ -256,11 +294,12 @@ tklib.Tcl_IncrRefCount(obj) objects[i] = obj - res = tklib.Tcl_EvalObjv(self.interp, argc, objects, flags) - if res == tklib.TCL_ERROR: - self.raiseTclError() - else: - result = self._callResult() + with self._tcl_lock: + res = tklib.Tcl_EvalObjv(self.interp, argc, objects, flags) + if res == tklib.TCL_ERROR: + self.raiseTclError() + else: + result = self._callResult() finally: for obj in objects: if obj: @@ -280,17 +319,19 @@ def eval(self, script): self._check_tcl_appartment() - res = tklib.Tcl_Eval(self.interp, script) - if res == tklib.TCL_ERROR: - self.raiseTclError() - return tkffi.string(tklib.Tcl_GetStringResult(self.interp)) + with self._tcl_lock: + res = tklib.Tcl_Eval(self.interp, script) + if res == tklib.TCL_ERROR: + self.raiseTclError() + return tkffi.string(tklib.Tcl_GetStringResult(self.interp)) def evalfile(self, filename): self._check_tcl_appartment() - res = tklib.Tcl_EvalFile(self.interp, filename) - if res == tklib.TCL_ERROR: - self.raiseTclError() - return tkffi.string(tklib.Tcl_GetStringResult(self.interp)) + with self._tcl_lock: + res = tklib.Tcl_EvalFile(self.interp, filename) + if res == tklib.TCL_ERROR: + self.raiseTclError() + return tkffi.string(tklib.Tcl_GetStringResult(self.interp)) def split(self, arg): if isinstance(arg, tuple): @@ -375,7 +416,10 @@ if self.threaded: result = tklib.Tcl_DoOneEvent(0) else: - raise NotImplementedError("TCL configured without threads") + with self._tcl_lock: + result = tklib.Tcl_DoOneEvent(tklib.TCL_DONT_WAIT) + if result == 0: + time.sleep(self._busywaitinterval) if result < 0: break diff --git a/lib_pypy/_tkinter/tklib.py b/lib_pypy/_tkinter/tklib.py --- a/lib_pypy/_tkinter/tklib.py +++ b/lib_pypy/_tkinter/tklib.py @@ -1,6 +1,7 @@ # C bindings with libtcl and libtk. from cffi import FFI +import sys tkffi = FFI() @@ -18,6 +19,8 @@ #define TCL_EVAL_DIRECT ... #define TCL_EVAL_GLOBAL ... +#define TCL_DONT_WAIT ... + typedef unsigned short Tcl_UniChar; typedef ... Tcl_Interp; typedef ...* Tcl_ThreadId; @@ -102,6 +105,17 @@ int Tk_GetNumMainWindows(); """) +# XXX find a better way to detect paths +# XXX pick up CPPFLAGS and LDFLAGS and add to these paths? +if sys.platform.startswith("openbsd"): + incdirs = ['/usr/local/include/tcl8.5', '/usr/local/include/tk8.5', '/usr/X11R6/include'] + linklibs = ['tk85', 'tcl85'] + libdirs = ['/usr/local/lib', '/usr/X11R6/lib'] +else: + incdirs=['/usr/include/tcl'] + linklibs=['tcl', 'tk'] + libdirs = [] + tklib = tkffi.verify(""" #include #include @@ -109,6 +123,7 @@ char *get_tk_version() { return TK_VERSION; } char *get_tcl_version() { return TCL_VERSION; } """, -include_dirs=['/usr/include/tcl'], -libraries=['tcl', 'tk'], +include_dirs=incdirs, +libraries=linklibs, +library_dirs = libdirs ) diff --git a/lib_pypy/cffi.egg-info b/lib_pypy/cffi.egg-info --- a/lib_pypy/cffi.egg-info +++ b/lib_pypy/cffi.egg-info @@ -1,6 +1,6 @@ Metadata-Version: 1.0 Name: cffi -Version: 0.6 +Version: 0.7 Summary: Foreign Function Interface for Python calling C code. Home-page: http://cffi.readthedocs.org Author: Armin Rigo, Maciej Fijalkowski diff --git a/lib_pypy/cffi/__init__.py b/lib_pypy/cffi/__init__.py --- a/lib_pypy/cffi/__init__.py +++ b/lib_pypy/cffi/__init__.py @@ -4,5 +4,5 @@ from .api import FFI, CDefError, FFIError from .ffiplatform import VerificationError, VerificationMissing -__version__ = "0.7" -__version_info__ = (0, 7) +__version__ = "0.7.2" +__version_info__ = (0, 7, 2) diff --git a/lib_pypy/cffi/api.py b/lib_pypy/cffi/api.py --- a/lib_pypy/cffi/api.py +++ b/lib_pypy/cffi/api.py @@ -54,7 +54,8 @@ # _cffi_backend.so compiled. import _cffi_backend as backend from . import __version__ - assert backend.__version__ == __version__ + assert (backend.__version__ == __version__ or + backend.__version__ == __version__[:3]) # (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.) diff --git a/lib_pypy/cffi/commontypes.py b/lib_pypy/cffi/commontypes.py --- a/lib_pypy/cffi/commontypes.py +++ b/lib_pypy/cffi/commontypes.py @@ -30,7 +30,9 @@ elif result in model.PrimitiveType.ALL_PRIMITIVE_TYPES: result = model.PrimitiveType(result) else: - assert commontype != result + if commontype == result: + raise api.FFIError("Unsupported type: %r. Please file a bug " + "if you think it should be." % (commontype,)) result = resolve_common_type(result) # recursively assert isinstance(result, model.BaseTypeByIdentity) _CACHE[commontype] = result diff --git a/lib_pypy/cffi/cparser.py b/lib_pypy/cffi/cparser.py --- a/lib_pypy/cffi/cparser.py +++ b/lib_pypy/cffi/cparser.py @@ -290,13 +290,26 @@ # assume a primitive type. get it from .names, but reduce # synonyms to a single chosen combination names = list(type.names) - if names == ['signed'] or names == ['unsigned']: - names.append('int') - if names[0] == 'signed' and names != ['signed', 'char']: - names.pop(0) - if (len(names) > 1 and names[-1] == 'int' - and names != ['unsigned', 'int']): - names.pop() + if names != ['signed', 'char']: # keep this unmodified + prefixes = {} + while names: + name = names[0] + if name in ('short', 'long', 'signed', 'unsigned'): + prefixes[name] = prefixes.get(name, 0) + 1 + del names[0] + else: + break + # ignore the 'signed' prefix below, and reorder the others + newnames = [] + for prefix in ('unsigned', 'short', 'long'): + for i in range(prefixes.get(prefix, 0)): + newnames.append(prefix) + if not names: + names = ['int'] # implicitly + if names == ['int']: # but kill it if 'short' or 'long' + if 'short' in prefixes or 'long' in prefixes: + names = [] + names = newnames + names ident = ' '.join(names) if ident == 'void': return model.void_type @@ -500,8 +513,8 @@ self._partial_length = True return None # - raise api.FFIError("unsupported non-constant or " - "not immediately constant expression") + raise api.FFIError("unsupported expression: expected a " + "simple numeric constant") def _build_enum_type(self, explicit_name, decls): if decls is not None: diff --git a/lib_pypy/cffi/vengine_gen.py b/lib_pypy/cffi/vengine_gen.py --- a/lib_pypy/cffi/vengine_gen.py +++ b/lib_pypy/cffi/vengine_gen.py @@ -61,7 +61,9 @@ def load_library(self): # import it with the CFFI backend backend = self.ffi._backend - module = backend.load_library(self.verifier.modulefilename) + # needs to make a path that contains '/', on Posix + filename = os.path.join(os.curdir, self.verifier.modulefilename) + module = backend.load_library(filename) # # call loading_gen_struct() to get the struct layout inferred by # the C compiler diff --git a/lib_pypy/ctypes_config_cache/syslog.ctc.py b/lib_pypy/ctypes_config_cache/syslog.ctc.py deleted file mode 100644 --- a/lib_pypy/ctypes_config_cache/syslog.ctc.py +++ /dev/null @@ -1,75 +0,0 @@ -""" -'ctypes_configure' source for syslog.py. -Run this to rebuild _syslog_cache.py. -""" - -from ctypes_configure.configure import (configure, - ExternalCompilationInfo, ConstantInteger, DefinedConstantInteger) -import dumpcache - - -_CONSTANTS = ( - 'LOG_EMERG', - 'LOG_ALERT', - 'LOG_CRIT', - 'LOG_ERR', - 'LOG_WARNING', - 'LOG_NOTICE', - 'LOG_INFO', - 'LOG_DEBUG', - - 'LOG_PID', - 'LOG_CONS', - 'LOG_NDELAY', - - 'LOG_KERN', - 'LOG_USER', - 'LOG_MAIL', - 'LOG_DAEMON', - 'LOG_AUTH', - 'LOG_LPR', - 'LOG_LOCAL0', - 'LOG_LOCAL1', - 'LOG_LOCAL2', - 'LOG_LOCAL3', - 'LOG_LOCAL4', - 'LOG_LOCAL5', - 'LOG_LOCAL6', - 'LOG_LOCAL7', -) -_OPTIONAL_CONSTANTS = ( - 'LOG_NOWAIT', - 'LOG_PERROR', - - 'LOG_SYSLOG', - 'LOG_CRON', - 'LOG_UUCP', - 'LOG_NEWS', -) - -# Constant aliases if there are not defined -_ALIAS = ( - ('LOG_SYSLOG', 'LOG_DAEMON'), - ('LOG_CRON', 'LOG_DAEMON'), - ('LOG_NEWS', 'LOG_MAIL'), - ('LOG_UUCP', 'LOG_MAIL'), -) - -class SyslogConfigure: - _compilation_info_ = ExternalCompilationInfo(includes=['sys/syslog.h']) -for key in _CONSTANTS: - setattr(SyslogConfigure, key, ConstantInteger(key)) -for key in _OPTIONAL_CONSTANTS: - setattr(SyslogConfigure, key, DefinedConstantInteger(key)) - -config = configure(SyslogConfigure) -for key in _OPTIONAL_CONSTANTS: - if config[key] is None: - del config[key] -for alias, key in _ALIAS: - config.setdefault(alias, config[key]) - -all_constants = config.keys() -all_constants.sort() -config['ALL_CONSTANTS'] = tuple(all_constants) -dumpcache.dumpcache2('syslog', config) diff --git a/lib_pypy/datetime.py b/lib_pypy/datetime.py --- a/lib_pypy/datetime.py +++ b/lib_pypy/datetime.py @@ -40,9 +40,9 @@ # for all computations. See the book for algorithms for converting between # proleptic Gregorian ordinals and many other calendar systems. -_DAYS_IN_MONTH = [None, 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31] +_DAYS_IN_MONTH = [-1, 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31] -_DAYS_BEFORE_MONTH = [None] +_DAYS_BEFORE_MONTH = [-1] dbm = 0 for dim in _DAYS_IN_MONTH[1:]: _DAYS_BEFORE_MONTH.append(dbm) diff --git a/lib_pypy/greenlet.py b/lib_pypy/greenlet.py --- a/lib_pypy/greenlet.py +++ b/lib_pypy/greenlet.py @@ -1,3 +1,4 @@ +import sys import _continuation __version__ = "0.4.0" @@ -5,7 +6,7 @@ # ____________________________________________________________ # Exceptions -class GreenletExit(Exception): +class GreenletExit(BaseException): """This special exception does not propagate to the parent greenlet; it can be used to kill a single greenlet.""" @@ -46,16 +47,16 @@ if parent is not None: self.parent = parent - def switch(self, *args): + def switch(self, *args, **kwds): "Switch execution to this greenlet, optionally passing the values " "given as argument(s). Returns the value passed when switching back." - return self.__switch('switch', args) + return self.__switch('switch', (args, kwds)) def throw(self, typ=GreenletExit, val=None, tb=None): "raise exception in greenlet, return value passed when switching back" return self.__switch('throw', typ, val, tb) - def __switch(target, methodname, *args): + def __switch(target, methodname, *baseargs): current = getcurrent() # while not (target.__main or _continulet.is_pending(target)): @@ -65,9 +66,9 @@ greenlet_func = _greenlet_start else: greenlet_func = _greenlet_throw - _continulet.__init__(target, greenlet_func, *args) + _continulet.__init__(target, greenlet_func, *baseargs) methodname = 'switch' - args = () + baseargs = () target.__started = True break # already done, go to the parent instead @@ -75,14 +76,27 @@ # up the 'parent' explicitly. Good enough, because a Ctrl-C # will show that the program is caught in this loop here.) target = target.parent + # convert a "raise GreenletExit" into "return GreenletExit" + if methodname == 'throw': + try: + raise baseargs[0], baseargs[1] + except GreenletExit, e: + methodname = 'switch' + baseargs = (((e,), {}),) + except: + baseargs = sys.exc_info()[:2] + baseargs[2:] # try: unbound_method = getattr(_continulet, methodname) - args = unbound_method(current, *args, to=target) + args, kwds = unbound_method(current, *baseargs, to=target) finally: _tls.current = current # - if len(args) == 1: + if kwds: + if args: + return args, kwds + return kwds + elif len(args) == 1: return args[0] else: return args @@ -129,18 +143,22 @@ _tls.current = gmain def _greenlet_start(greenlet, args): + args, kwds = args _tls.current = greenlet try: - res = greenlet.run(*args) + res = greenlet.run(*args, **kwds) except GreenletExit, e: res = e finally: _continuation.permute(greenlet, greenlet.parent) - return (res,) + return ((res,), None) def _greenlet_throw(greenlet, exc, value, tb): _tls.current = greenlet try: raise exc, value, tb + except GreenletExit, e: + res = e finally: _continuation.permute(greenlet, greenlet.parent) + return ((res,), None) diff --git a/lib_pypy/grp.py b/lib_pypy/grp.py --- a/lib_pypy/grp.py +++ b/lib_pypy/grp.py @@ -8,6 +8,7 @@ from ctypes import Structure, c_char_p, c_int, POINTER from ctypes_support import standard_c_lib as libc +import _structseq try: from __pypy__ import builtinify except ImportError: builtinify = lambda f: f @@ -23,32 +24,13 @@ ('gr_mem', POINTER(c_char_p)), ) -class Group(object): - def __init__(self, gr_name, gr_passwd, gr_gid, gr_mem): - self.gr_name = gr_name - self.gr_passwd = gr_passwd - self.gr_gid = gr_gid - self.gr_mem = gr_mem +class struct_group: + __metaclass__ = _structseq.structseqtype - def __getitem__(self, item): - if item == 0: - return self.gr_name - elif item == 1: - return self.gr_passwd - elif item == 2: - return self.gr_gid - elif item == 3: - return self.gr_mem - else: - raise IndexError(item) - - def __len__(self): - return 4 - - def __repr__(self): - return str((self.gr_name, self.gr_passwd, self.gr_gid, self.gr_mem)) - - # whatever else... + gr_name = _structseq.structseqfield(0) + gr_passwd = _structseq.structseqfield(1) + gr_gid = _structseq.structseqfield(2) + gr_mem = _structseq.structseqfield(3) libc.getgrgid.argtypes = [gid_t] libc.getgrgid.restype = POINTER(GroupStruct) @@ -71,8 +53,8 @@ while res.contents.gr_mem[i]: mem.append(res.contents.gr_mem[i]) i += 1 - return Group(res.contents.gr_name, res.contents.gr_passwd, - res.contents.gr_gid, mem) + return struct_group((res.contents.gr_name, res.contents.gr_passwd, + res.contents.gr_gid, mem)) @builtinify def getgrgid(gid): diff --git a/lib_pypy/pyrepl/curses.py b/lib_pypy/pyrepl/curses.py --- a/lib_pypy/pyrepl/curses.py +++ b/lib_pypy/pyrepl/curses.py @@ -19,11 +19,15 @@ # CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN # CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. -# avoid importing the whole curses, if possible -try: +# If we are running on top of pypy, we import only _minimal_curses. +# Don't try to fall back to _curses, because that's going to use cffi +# and fall again more loudly. +import sys +if '__pypy__' in sys.builtin_module_names: # pypy case import _minimal_curses as _curses -except ImportError: +else: + # cpython case try: import _curses except ImportError: diff --git a/lib_pypy/readline.egg-info b/lib_pypy/readline.egg-info new file mode 100644 --- /dev/null +++ b/lib_pypy/readline.egg-info @@ -0,0 +1,10 @@ +Metadata-Version: 1.0 +Name: readline +Version: 6.2.4.1 +Summary: Hack to make "pip install readline" happy and do nothing +Home-page: UNKNOWN +Author: UNKNOWN +Author-email: UNKNOWN +License: UNKNOWN +Description: UNKNOWN +Platform: UNKNOWN diff --git a/lib_pypy/syslog.py b/lib_pypy/syslog.py --- a/lib_pypy/syslog.py +++ b/lib_pypy/syslog.py @@ -1,3 +1,4 @@ +# this cffi version was rewritten based on the # ctypes implementation: Victor Stinner, 2008-05-08 """ This module provides an interface to the Unix syslog library routines. @@ -9,34 +10,84 @@ if sys.platform == 'win32': raise ImportError("No syslog on Windows") -# load the platform-specific cache made by running syslog.ctc.py -from ctypes_config_cache._syslog_cache import * - -from ctypes_support import standard_c_lib as libc -from ctypes import c_int, c_char_p +from cffi import FFI try: from __pypy__ import builtinify except ImportError: builtinify = lambda f: f +ffi = FFI() -# Real prototype is: -# void syslog(int priority, const char *format, ...); -# But we also need format ("%s") and one format argument (message) -_syslog = libc.syslog -_syslog.argtypes = (c_int, c_char_p, c_char_p) -_syslog.restype = None +ffi.cdef(""" +/* mandatory constants */ +#define LOG_EMERG ... +#define LOG_ALERT ... +#define LOG_CRIT ... +#define LOG_ERR ... +#define LOG_WARNING ... +#define LOG_NOTICE ... +#define LOG_INFO ... +#define LOG_DEBUG ... -_openlog = libc.openlog -_openlog.argtypes = (c_char_p, c_int, c_int) -_openlog.restype = None +#define LOG_PID ... +#define LOG_CONS ... +#define LOG_NDELAY ... -_closelog = libc.closelog -_closelog.argtypes = None -_closelog.restype = None +#define LOG_KERN ... +#define LOG_USER ... +#define LOG_MAIL ... +#define LOG_DAEMON ... +#define LOG_AUTH ... +#define LOG_LPR ... +#define LOG_LOCAL0 ... +#define LOG_LOCAL1 ... +#define LOG_LOCAL2 ... +#define LOG_LOCAL3 ... +#define LOG_LOCAL4 ... +#define LOG_LOCAL5 ... +#define LOG_LOCAL6 ... +#define LOG_LOCAL7 ... -_setlogmask = libc.setlogmask -_setlogmask.argtypes = (c_int,) -_setlogmask.restype = c_int +/* optional constants, gets defined to -919919 if missing */ +#define LOG_NOWAIT ... +#define LOG_PERROR ... + +/* aliased constants, gets defined as some other constant if missing */ +#define LOG_SYSLOG ... +#define LOG_CRON ... +#define LOG_UUCP ... +#define LOG_NEWS ... + +/* functions */ +void openlog(const char *ident, int option, int facility); +void syslog(int priority, const char *format, const char *string); +// NB. the signature of syslog() is specialized to the only case we use +void closelog(void); +int setlogmask(int mask); +""") + +lib = ffi.verify(""" +#include + +#ifndef LOG_NOWAIT +#define LOG_NOWAIT -919919 +#endif +#ifndef LOG_PERROR +#define LOG_PERROR -919919 +#endif +#ifndef LOG_SYSLOG +#define LOG_SYSLOG LOG_DAEMON +#endif +#ifndef LOG_CRON +#define LOG_CRON LOG_DAEMON +#endif +#ifndef LOG_UUCP +#define LOG_UUCP LOG_MAIL +#endif +#ifndef LOG_NEWS +#define LOG_NEWS LOG_MAIL +#endif +""") + _S_log_open = False _S_ident_o = None @@ -52,12 +103,17 @@ return None @builtinify -def openlog(ident=None, logoption=0, facility=LOG_USER): +def openlog(ident=None, logoption=0, facility=lib.LOG_USER): global _S_ident_o, _S_log_open if ident is None: ident = _get_argv() - _S_ident_o = c_char_p(ident) # keepalive - _openlog(_S_ident_o, logoption, facility) + if ident is None: + _S_ident_o = ffi.NULL + elif isinstance(ident, str): + _S_ident_o = ffi.new("char[]", ident) # keepalive + else: + raise TypeError("'ident' must be a string or None") + lib.openlog(_S_ident_o, logoption, facility) _S_log_open = True @builtinify @@ -69,19 +125,19 @@ # if log is not opened, open it now if not _S_log_open: openlog() - _syslog(priority, "%s", message) + lib.syslog(priority, "%s", message) @builtinify def closelog(): global _S_log_open, S_ident_o if _S_log_open: - _closelog() + lib.closelog() _S_log_open = False _S_ident_o = None @builtinify def setlogmask(mask): - return _setlogmask(mask) + return lib.setlogmask(mask) @builtinify def LOG_MASK(pri): @@ -91,8 +147,15 @@ def LOG_UPTO(pri): return (1 << (pri + 1)) - 1 -__all__ = ALL_CONSTANTS + ( +__all__ = [] + +for name in sorted(lib.__dict__): + if name.startswith('LOG_'): + value = getattr(lib, name) + if value != -919919: + globals()[name] = value + __all__.append(name) + +__all__ = tuple(__all__) + ( 'openlog', 'syslog', 'closelog', 'setlogmask', 'LOG_MASK', 'LOG_UPTO') - -del ALL_CONSTANTS diff --git a/pypy/config/pypyoption.py b/pypy/config/pypyoption.py --- a/pypy/config/pypyoption.py +++ b/pypy/config/pypyoption.py @@ -35,7 +35,7 @@ "thread", "itertools", "pyexpat", "_ssl", "cpyext", "array", "binascii", "_multiprocessing", '_warnings', "_collections", "_multibytecodec", "micronumpy", "_ffi", - "_continuation", "_cffi_backend", "_csv", "cppyy"] + "_continuation", "_cffi_backend", "_csv", "cppyy", "_pypyjson"] )) translation_modules = default_modules.copy() @@ -48,11 +48,6 @@ "termios", "_minimal_curses", ])) -working_oo_modules = default_modules.copy() -working_oo_modules.update(dict.fromkeys( - ["_md5", "_sha", "cStringIO", "itertools"] -)) - # XXX this should move somewhere else, maybe to platform ("is this posixish" # check or something) if sys.platform == "win32": @@ -132,11 +127,6 @@ pypy_optiondescription = OptionDescription("objspace", "Object Space Options", [ - OptionDescription("opcodes", "opcodes to enable in the interpreter", [ - BoolOption("CALL_METHOD", "emit a special bytecode for expr.name()", - default=False), - ]), - OptionDescription("usemodules", "Which Modules should be used", [ BoolOption(modname, "use module %s" % (modname, ), default=modname in default_modules, @@ -144,7 +134,7 @@ requires=module_dependencies.get(modname, []), suggests=module_suggests.get(modname, []), negation=modname not in essential_modules, - validator=get_module_validator(modname)) + ) #validator=get_module_validator(modname)) for modname in all_modules]), BoolOption("allworkingmodules", "use as many working modules as possible", @@ -264,9 +254,6 @@ BoolOption("optimized_int_add", "special case the addition of two integers in BINARY_ADD", default=False), - BoolOption("optimized_comparison_op", - "special case the comparison of integers", - default=False), BoolOption("optimized_list_getitem", "special case the 'list[integer]' expressions", default=False), @@ -312,7 +299,6 @@ # all the good optimizations for PyPy should be listed here if level in ['2', '3', 'jit']: - config.objspace.opcodes.suggest(CALL_METHOD=True) config.objspace.std.suggest(withrangelist=True) config.objspace.std.suggest(withmethodcache=True) config.objspace.std.suggest(withprebuiltchar=True) @@ -340,25 +326,20 @@ if not IS_64_BITS: config.objspace.std.suggest(withsmalllong=True) - # some optimizations have different effects depending on the typesystem - if type_system == 'ootype': - config.objspace.std.suggest(multimethods="doubledispatch") - # extra optimizations with the JIT if level == 'jit': config.objspace.std.suggest(withcelldict=True) - config.objspace.std.suggest(withmapdict=True) + if not config.translation.stm: + config.objspace.std.suggest(withmapdict=True) # tweaks some parameters with STM if config.translation.stm: config.objspace.std.suggest(methodcachesizeexp=9) + # XXX try at some point to see if withmapdict=True would make sense def enable_allworkingmodules(config): - if config.translation.type_system == 'ootype': - modules = working_oo_modules - else: - modules = working_modules + modules = working_modules if config.translation.sandbox: modules = default_modules # ignore names from 'essential_modules', notably 'exceptions', which diff --git a/pypy/doc/_ref.txt b/pypy/doc/_ref.txt --- a/pypy/doc/_ref.txt +++ b/pypy/doc/_ref.txt @@ -99,8 +99,6 @@ .. _`rpython/rtyper/memory/gc/hybrid.py`: https://bitbucket.org/pypy/pypy/src/default/rpython/rtyper/memory/gc/hybrid.py .. _`rpython/rtyper/memory/gc/minimarkpage.py`: https://bitbucket.org/pypy/pypy/src/default/rpython/rtyper/memory/gc/minimarkpage.py .. _`rpython/rtyper/memory/gc/semispace.py`: https://bitbucket.org/pypy/pypy/src/default/rpython/rtyper/memory/gc/semispace.py -.. _`rpython/rtyper/ootypesystem/`: https://bitbucket.org/pypy/pypy/src/default/rpython/rtyper/ootypesystem/ -.. _`rpython/rtyper/ootypesystem/ootype.py`: https://bitbucket.org/pypy/pypy/src/default/rpython/rtyper/ootypesystem/ootype.py .. _`rpython/rtyper/rint.py`: https://bitbucket.org/pypy/pypy/src/default/rpython/rtyper/rint.py .. _`rpython/rtyper/rlist.py`: https://bitbucket.org/pypy/pypy/src/default/rpython/rtyper/rlist.py .. _`rpython/rtyper/rmodel.py`: https://bitbucket.org/pypy/pypy/src/default/rpython/rtyper/rmodel.py diff --git a/pypy/doc/cli-backend.rst b/pypy/doc/cli-backend.rst deleted file mode 100644 --- a/pypy/doc/cli-backend.rst +++ /dev/null @@ -1,455 +0,0 @@ -=============== -The CLI backend -=============== - -The goal of GenCLI is to compile RPython programs to the CLI virtual -machine. - - -Target environment and language -=============================== - -The target of GenCLI is the Common Language Infrastructure environment -as defined by the `Standard Ecma 335`_. - -While in an ideal world we might suppose GenCLI to run fine with -every implementation conforming to that standard, we know the world we -live in is far from ideal, so extra efforts can be needed to maintain -compatibility with more than one implementation. - -At the moment of writing the two most popular implementations of the -standard are supported: Microsoft Common Language Runtime (CLR) and -Mono. - -Then we have to choose how to generate the real executables. There are -two main alternatives: generating source files in some high level -language (such as C#) or generating assembly level code in -Intermediate Language (IL). - -The IL approach is much faster during the code generation -phase, because it doesn't need to call a compiler. By contrast the -high level approach has two main advantages: - - - the code generation part could be easier because the target - language supports high level control structures such as - structured loops; - - - the generated executables take advantage of compiler's - optimizations. - -In reality the first point is not an advantage in the PyPy context, -because the `flow graph`_ we start from is quite low level and Python -loops are already expressed in terms of branches (i.e., gotos). - -About the compiler optimizations we must remember that the flow graph -we receive from earlier stages is already optimized: PyPy implements -a number of optimizations such a constant propagation and -dead code removal, so it's not obvious if the compiler could -do more. - -Moreover by emitting IL instruction we are not constrained to rely on -compiler choices but can directly choose how to map CLI opcodes: since -the backend often know more than the compiler about the context, we -might expect to produce more efficient code by selecting the most -appropriate instruction; e.g., we can check for arithmetic overflow -only when strictly necessary. - -The last but not least reason for choosing the low level approach is -flexibility in how to get an executable starting from the IL code we -generate: - - - write IL code to a file, then call the ilasm assembler; - - - directly generate code on the fly by accessing the facilities - exposed by the System.Reflection.Emit API. - - -Handling platform differences -============================= - -Since our goal is to support both Microsoft CLR we have to handle the -differences between the twos; in particular the main differences are -in the name of the helper tools we need to call: - -=============== ======== ====== -Tool CLR Mono -=============== ======== ====== From noreply at buildbot.pypy.org Sun Sep 15 12:23:23 2013 From: noreply at buildbot.pypy.org (arigo) Date: Sun, 15 Sep 2013 12:23:23 +0200 (CEST) Subject: [pypy-commit] pypy default: Reintroduce the hints for register location through a JUMP. Message-ID: <20130915102323.627EF1C0162@cobra.cs.uni-duesseldorf.de> Author: Armin Rigo Branch: Changeset: r66952:f0beca98ab6f Date: 2013-09-15 12:00 +0200 http://bitbucket.org/pypy/pypy/changeset/f0beca98ab6f/ Log: Reintroduce the hints for register location through a JUMP. 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 @@ -68,14 +68,27 @@ function(arg, node.val) node = node.next - def pop(self, size, tp): + def pop(self, size, tp, hint=-1): if size == 2: return self._pop_two(tp) assert size == 1 if not self.master_node: return None node = self.master_node - self.master_node = node.next + # + if hint >= 0: + prev_node = node + while prev_node.next: + if prev_node.next.val == hint: + node = prev_node.next + prev_node.next = node.next + break + prev_node = prev_node.next + else: + self.master_node = node.next + else: + self.master_node = node.next + # return self.fm.frame_pos(node.val, tp) def _candidate(self, node): @@ -131,8 +144,7 @@ def __init__(self, start_free_depth=0, freelist=None): self.bindings = {} self.current_frame_depth = start_free_depth - # we disable hints for now - #self.hint_frame_locations = {} + self.hint_frame_pos = {} self.freelist = LinkedList(self, freelist) def get_frame_depth(self): @@ -148,22 +160,16 @@ return self.bindings[box] except KeyError: pass - # check if we have a hint for this box - #if box in self.hint_frame_locations: - # # if we do, try to reuse the location for this box - # loc = self.hint_frame_locations[box] - # if self.try_to_reuse_location(box, loc): - # return loc - ## no valid hint. make up a new free location return self.get_new_loc(box) def get_new_loc(self, box): size = self.frame_size(box.type) + hint = self.hint_frame_pos.get(box, -1) # frame_depth is rounded up to a multiple of 'size', assuming # that 'size' is a power of two. The reason for doing so is to # avoid obscure issues in jump.py with stack locations that try # to move from position (6,7) to position (7,8). - newloc = self.freelist.pop(size, box.type) + newloc = self.freelist.pop(size, box.type, hint) if newloc is None: # index = self.get_frame_depth() @@ -232,23 +238,6 @@ all[node.val] = 1 node = node.next - def try_to_reuse_location(self, box, loc): - xxx - index = self.get_loc_index(loc) - if index < 0: - return False - size = self.frame_size(box.type) - for i in range(size): - while (index + i) >= len(self.used): - self.used.append(False) - if self.used[index + i]: - return False # already in use - # good, we can reuse the location - for i in range(size): - self.used[index + i] = True - self.bindings[box] = loc - return True - @staticmethod def _gather_gcroots(lst, var): lst.append(var) diff --git a/rpython/jit/backend/llsupport/test/test_regalloc.py b/rpython/jit/backend/llsupport/test/test_regalloc.py --- a/rpython/jit/backend/llsupport/test/test_regalloc.py +++ b/rpython/jit/backend/llsupport/test/test_regalloc.py @@ -379,48 +379,23 @@ def test_hint_frame_locations_1(self): - py.test.skip("xxx") - b0, = newboxes(0) - fm = TFrameManager() - loc123 = FakeFramePos(123, INT) - fm.hint_frame_locations[b0] = loc123 - assert fm.get_frame_depth() == 0 - loc = fm.loc(b0) - assert loc == loc123 - assert fm.get_frame_depth() == 124 - - def test_hint_frame_locations_2(self): - py.test.skip("xxx") - b0, b1, b2 = newboxes(0, 1, 2) - longevity = {b0: (0, 1), b1: (0, 2), b2: (0, 2)} - fm = TFrameManager() - asm = MockAsm() - rm = RegisterManager(longevity, frame_manager=fm, assembler=asm) - rm.force_allocate_reg(b0) - rm.force_allocate_reg(b1) - rm.force_allocate_reg(b2) - rm.force_spill_var(b0) - loc = rm.loc(b0) - assert isinstance(loc, FakeFramePos) - assert fm.get_loc_index(loc) == 0 - rm.position = 1 - assert fm.used == [True] - rm.possibly_free_var(b0) - assert fm.used == [False] - # - fm.hint_frame_locations[b1] = loc - rm.force_spill_var(b1) - loc1 = rm.loc(b1) - assert loc1 == loc - assert fm.used == [True] - # - fm.hint_frame_locations[b2] = loc - rm.force_spill_var(b2) - loc2 = rm.loc(b2) - assert loc2 != loc1 # because it was not free - assert fm.used == [True, True] - # - rm._check_invariants() + for hint_value in range(11): + b0, = newboxes(0) + fm = TFrameManager() + fm.hint_frame_pos[b0] = hint_value + blist = newboxes(*range(10)) + for b1 in blist: + fm.loc(b1) + for b1 in blist: + fm.mark_as_free(b1) + assert fm.get_frame_depth() == 10 + loc = fm.loc(b0) + if hint_value < 10: + expected = hint_value + else: + expected = 0 + assert fm.get_loc_index(loc) == expected + assert fm.get_frame_depth() == 10 def test_linkedlist(self): class Loc(object): 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 @@ -1197,7 +1197,6 @@ # optimization only: fill in the 'hint_frame_locations' dictionary # of 'fm' based on the JUMP at the end of the loop, by looking # at where we would like the boxes to be after the jump. - return # XXX disabled for now op = operations[-1] if op.getopnum() != rop.JUMP: return @@ -1223,7 +1222,7 @@ if isinstance(box, Box): loc = arglocs[i] if isinstance(loc, FrameLoc): - self.fm.hint_frame_locations[box] = loc + self.fm.hint_frame_pos[box] = self.fm.get_loc_index(loc) def consider_jump(self, op): assembler = self.assembler @@ -1325,13 +1324,9 @@ # end of the same loop, i.e. if what we are compiling is a single # loop that ends up jumping to this LABEL, then we can now provide # the hints about the expected position of the spilled variables. - - # XXX we never compile code like that? - # YYY of course, because compute_hint_frame_locations() is disabled. - # re-enable this once we re-enable it! - #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) + 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_guard_not_forced_2(self, op): self.rm.before_call(op.getfailargs(), save_all_regs=True) From noreply at buildbot.pypy.org Sun Sep 15 12:23:24 2013 From: noreply at buildbot.pypy.org (arigo) Date: Sun, 15 Sep 2013 12:23:24 +0200 (CEST) Subject: [pypy-commit] pypy default: Comment. Message-ID: <20130915102324.98D581C0162@cobra.cs.uni-duesseldorf.de> Author: Armin Rigo Branch: Changeset: r66953:caa51c7055cf Date: 2013-09-15 12:18 +0200 http://bitbucket.org/pypy/pypy/changeset/caa51c7055cf/ Log: Comment. 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 @@ -77,6 +77,11 @@ node = self.master_node # if hint >= 0: + # Look for and remove the Node with the .val matching 'hint'. + # If not found, fall back to removing the first Node. + # Note that the loop below ignores the first Node, but + # even if by chance it is the one with the correct .val, + # it will be the one we remove at the end anyway. prev_node = node while prev_node.next: if prev_node.next.val == hint: From noreply at buildbot.pypy.org Sun Sep 15 17:00:38 2013 From: noreply at buildbot.pypy.org (arigo) Date: Sun, 15 Sep 2013 17:00:38 +0200 (CEST) Subject: [pypy-commit] pypy default: Rename the flag "threadsafe" to rffi.llexternal() into "releasegil", which Message-ID: <20130915150038.30FAC1C0842@cobra.cs.uni-duesseldorf.de> Author: Armin Rigo Branch: Changeset: r66954:837ec9da7885 Date: 2013-09-15 16:59 +0200 http://bitbucket.org/pypy/pypy/changeset/837ec9da7885/ Log: Rename the flag "threadsafe" to rffi.llexternal() into "releasegil", which is what it really means. diff --git a/pypy/module/__pypy__/interp_time.py b/pypy/module/__pypy__/interp_time.py --- a/pypy/module/__pypy__/interp_time.py +++ b/pypy/module/__pypy__/interp_time.py @@ -48,11 +48,11 @@ c_clock_gettime = rffi.llexternal("clock_gettime", [lltype.Signed, lltype.Ptr(TIMESPEC)], rffi.INT, - compilation_info=CConfig._compilation_info_, threadsafe=False + compilation_info=CConfig._compilation_info_, releasegil=False ) c_clock_getres = rffi.llexternal("clock_getres", [lltype.Signed, lltype.Ptr(TIMESPEC)], rffi.INT, - compilation_info=CConfig._compilation_info_, threadsafe=False + compilation_info=CConfig._compilation_info_, releasegil=False ) @unwrap_spec(clk_id="c_int") 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 @@ -28,7 +28,7 @@ 'CreateSemaphoreA', [rffi.VOIDP, rffi.LONG, rffi.LONG, rwin32.LPCSTR], rwin32.HANDLE) _CloseHandle = rwin32.winexternal('CloseHandle', [rwin32.HANDLE], - rwin32.BOOL, threadsafe=False) + rwin32.BOOL, releasegil=False) _ReleaseSemaphore = rwin32.winexternal( 'ReleaseSemaphore', [rwin32.HANDLE, rffi.LONG, rffi.LONGP], rwin32.BOOL) @@ -82,8 +82,8 @@ _sem_open = external('sem_open', [rffi.CCHARP, rffi.INT, rffi.INT, rffi.UINT], SEM_T) - # tread sem_close as not threadsafe for now to be able to use the __del__ - _sem_close = external('sem_close', [SEM_T], rffi.INT, threadsafe=False) + # sem_close is releasegil=False to be able to use it in the __del__ + _sem_close = external('sem_close', [SEM_T], rffi.INT, releasegil=False) _sem_unlink = external('sem_unlink', [rffi.CCHARP], rffi.INT) _sem_wait = external('sem_wait', [SEM_T], rffi.INT) _sem_trywait = external('sem_trywait', [SEM_T], rffi.INT) 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 @@ -144,12 +144,12 @@ BZ2_bzCompressInit = external('BZ2_bzCompressInit', [bz_stream, rffi.INT, rffi.INT, rffi.INT], rffi.INT) BZ2_bzCompressEnd = external('BZ2_bzCompressEnd', [bz_stream], rffi.INT, - threadsafe=False) + releasegil=False) BZ2_bzCompress = external('BZ2_bzCompress', [bz_stream, rffi.INT], rffi.INT) BZ2_bzDecompressInit = external('BZ2_bzDecompressInit', [bz_stream, rffi.INT, rffi.INT], rffi.INT) BZ2_bzDecompressEnd = external('BZ2_bzDecompressEnd', [bz_stream], rffi.INT, - threadsafe=False) + releasegil=False) BZ2_bzDecompress = external('BZ2_bzDecompress', [bz_stream], rffi.INT) def _catch_bz2_error(space, bzerror): diff --git a/pypy/module/cppyy/capi/builtin_capi.py b/pypy/module/cppyy/capi/builtin_capi.py --- a/pypy/module/cppyy/capi/builtin_capi.py +++ b/pypy/module/cppyy/capi/builtin_capi.py @@ -27,7 +27,7 @@ _c_num_scopes = rffi.llexternal( "cppyy_num_scopes", [C_SCOPE], rffi.INT, - threadsafe=ts_reflect, + releasegil=ts_reflect, compilation_info=backend.eci) def c_num_scopes(space, cppscope): return _c_num_scopes(cppscope.handle) @@ -41,28 +41,28 @@ _c_resolve_name = rffi.llexternal( "cppyy_resolve_name", [rffi.CCHARP], rffi.CCHARP, - threadsafe=ts_reflect, + releasegil=ts_reflect, compilation_info=backend.eci) def c_resolve_name(space, name): return charp2str_free(space, _c_resolve_name(name)) _c_get_scope_opaque = rffi.llexternal( "cppyy_get_scope", [rffi.CCHARP], C_SCOPE, - threadsafe=ts_reflect, + releasegil=ts_reflect, compilation_info=backend.eci) def c_get_scope_opaque(space, name): return _c_get_scope_opaque(name) _c_get_template = rffi.llexternal( "cppyy_get_template", [rffi.CCHARP], C_TYPE, - threadsafe=ts_reflect, + releasegil=ts_reflect, compilation_info=backend.eci) def c_get_template(space, name): return _c_get_template(name) _c_actual_class = rffi.llexternal( "cppyy_actual_class", [C_TYPE, C_OBJECT], C_TYPE, - threadsafe=ts_reflect, + releasegil=ts_reflect, compilation_info=backend.eci) def c_actual_class(space, cppclass, cppobj): return _c_actual_class(cppclass.handle, cppobj) @@ -71,21 +71,21 @@ _c_allocate = rffi.llexternal( "cppyy_allocate", [C_TYPE], C_OBJECT, - threadsafe=ts_memory, + releasegil=ts_memory, compilation_info=backend.eci) def c_allocate(space, cppclass): return _c_allocate(cppclass.handle) _c_deallocate = rffi.llexternal( "cppyy_deallocate", [C_TYPE, C_OBJECT], lltype.Void, - threadsafe=ts_memory, + releasegil=ts_memory, compilation_info=backend.eci) def c_deallocate(space, cppclass, cppobject): _c_deallocate(cppclass.handle, cppobject) _c_destruct = rffi.llexternal( "cppyy_destruct", [C_TYPE, C_OBJECT], lltype.Void, - threadsafe=ts_call, + releasegil=ts_call, compilation_info=backend.eci) def c_destruct(space, cppclass, cppobject): _c_destruct(cppclass.handle, cppobject) @@ -94,63 +94,63 @@ _c_call_v = rffi.llexternal( "cppyy_call_v", [C_METHOD, C_OBJECT, rffi.INT, rffi.VOIDP], lltype.Void, - threadsafe=ts_call, + releasegil=ts_call, compilation_info=backend.eci) def c_call_v(space, cppmethod, cppobject, nargs, args): _c_call_v(cppmethod, cppobject, nargs, args) _c_call_b = rffi.llexternal( "cppyy_call_b", [C_METHOD, C_OBJECT, rffi.INT, rffi.VOIDP], rffi.UCHAR, - threadsafe=ts_call, + releasegil=ts_call, compilation_info=backend.eci) def c_call_b(space, cppmethod, cppobject, nargs, args): return _c_call_b(cppmethod, cppobject, nargs, args) _c_call_c = rffi.llexternal( "cppyy_call_c", [C_METHOD, C_OBJECT, rffi.INT, rffi.VOIDP], rffi.CHAR, - threadsafe=ts_call, + releasegil=ts_call, compilation_info=backend.eci) def c_call_c(space, cppmethod, cppobject, nargs, args): return _c_call_c(cppmethod, cppobject, nargs, args) _c_call_h = rffi.llexternal( "cppyy_call_h", [C_METHOD, C_OBJECT, rffi.INT, rffi.VOIDP], rffi.SHORT, - threadsafe=ts_call, + releasegil=ts_call, compilation_info=backend.eci) def c_call_h(space, cppmethod, cppobject, nargs, args): return _c_call_h(cppmethod, cppobject, nargs, args) _c_call_i = rffi.llexternal( "cppyy_call_i", [C_METHOD, C_OBJECT, rffi.INT, rffi.VOIDP], rffi.INT, - threadsafe=ts_call, + releasegil=ts_call, compilation_info=backend.eci) def c_call_i(space, cppmethod, cppobject, nargs, args): return _c_call_i(cppmethod, cppobject, nargs, args) _c_call_l = rffi.llexternal( "cppyy_call_l", [C_METHOD, C_OBJECT, rffi.INT, rffi.VOIDP], rffi.LONG, - threadsafe=ts_call, + releasegil=ts_call, compilation_info=backend.eci) def c_call_l(space, cppmethod, cppobject, nargs, args): return _c_call_l(cppmethod, cppobject, nargs, args) _c_call_ll = rffi.llexternal( "cppyy_call_ll", [C_METHOD, C_OBJECT, rffi.INT, rffi.VOIDP], rffi.LONGLONG, - threadsafe=ts_call, + releasegil=ts_call, compilation_info=backend.eci) def c_call_ll(space, cppmethod, cppobject, nargs, args): return _c_call_ll(cppmethod, cppobject, nargs, args) _c_call_f = rffi.llexternal( "cppyy_call_f", [C_METHOD, C_OBJECT, rffi.INT, rffi.VOIDP], rffi.FLOAT, - threadsafe=ts_call, + releasegil=ts_call, compilation_info=backend.eci) def c_call_f(space, cppmethod, cppobject, nargs, args): return _c_call_f(cppmethod, cppobject, nargs, args) _c_call_d = rffi.llexternal( "cppyy_call_d", [C_METHOD, C_OBJECT, rffi.INT, rffi.VOIDP], rffi.DOUBLE, - threadsafe=ts_call, + releasegil=ts_call, compilation_info=backend.eci) def c_call_d(space, cppmethod, cppobject, nargs, args): return _c_call_d(cppmethod, cppobject, nargs, args) @@ -158,14 +158,14 @@ _c_call_r = rffi.llexternal( "cppyy_call_r", [C_METHOD, C_OBJECT, rffi.INT, rffi.VOIDP], rffi.VOIDP, - threadsafe=ts_call, + releasegil=ts_call, compilation_info=backend.eci) def c_call_r(space, cppmethod, cppobject, nargs, args): return _c_call_r(cppmethod, cppobject, nargs, args) _c_call_s = rffi.llexternal( "cppyy_call_s", [C_METHOD, C_OBJECT, rffi.INT, rffi.VOIDP], rffi.CCHARP, - threadsafe=ts_call, + releasegil=ts_call, compilation_info=backend.eci) def c_call_s(space, cppmethod, cppobject, nargs, args): return _c_call_s(cppmethod, cppobject, nargs, args) @@ -173,14 +173,14 @@ _c_constructor = rffi.llexternal( "cppyy_constructor", [C_METHOD, C_TYPE, rffi.INT, rffi.VOIDP], C_OBJECT, - threadsafe=ts_call, + releasegil=ts_call, compilation_info=backend.eci) def c_constructor(space, cppmethod, cppobject, nargs, args): return _c_constructor(cppmethod, cppobject, nargs, args) _c_call_o = rffi.llexternal( "cppyy_call_o", [C_METHOD, C_OBJECT, rffi.INT, rffi.VOIDP, C_TYPE], rffi.LONG, - threadsafe=ts_call, + releasegil=ts_call, compilation_info=backend.eci) def c_call_o(space, method, cppobj, nargs, args, cppclass): return _c_call_o(method, cppobj, nargs, args, cppclass.handle) @@ -188,7 +188,7 @@ _c_get_methptr_getter = rffi.llexternal( "cppyy_get_methptr_getter", [C_SCOPE, C_INDEX], C_METHPTRGETTER_PTR, - threadsafe=ts_reflect, + releasegil=ts_reflect, compilation_info=backend.eci, elidable_function=True) def c_get_methptr_getter(space, cppscope, index): @@ -198,21 +198,21 @@ _c_allocate_function_args = rffi.llexternal( "cppyy_allocate_function_args", [rffi.SIZE_T], rffi.VOIDP, - threadsafe=ts_memory, + releasegil=ts_memory, compilation_info=backend.eci) def c_allocate_function_args(space, size): return _c_allocate_function_args(size) _c_deallocate_function_args = rffi.llexternal( "cppyy_deallocate_function_args", [rffi.VOIDP], lltype.Void, - threadsafe=ts_memory, + releasegil=ts_memory, compilation_info=backend.eci) def c_deallocate_function_args(space, args): _c_deallocate_function_args(args) _c_function_arg_sizeof = rffi.llexternal( "cppyy_function_arg_sizeof", [], rffi.SIZE_T, - threadsafe=ts_memory, + releasegil=ts_memory, compilation_info=backend.eci, elidable_function=True) def c_function_arg_sizeof(space): @@ -220,7 +220,7 @@ _c_function_arg_typeoffset = rffi.llexternal( "cppyy_function_arg_typeoffset", [], rffi.SIZE_T, - threadsafe=ts_memory, + releasegil=ts_memory, compilation_info=backend.eci, elidable_function=True) def c_function_arg_typeoffset(space): @@ -230,14 +230,14 @@ _c_is_namespace = rffi.llexternal( "cppyy_is_namespace", [C_SCOPE], rffi.INT, - threadsafe=ts_reflect, + releasegil=ts_reflect, compilation_info=backend.eci) def c_is_namespace(space, scope): return _c_is_namespace(scope) _c_is_enum = rffi.llexternal( "cppyy_is_enum", [rffi.CCHARP], rffi.INT, - threadsafe=ts_reflect, + releasegil=ts_reflect, compilation_info=backend.eci) def c_is_enum(space, name): return _c_is_enum(name) @@ -246,42 +246,42 @@ _c_final_name = rffi.llexternal( "cppyy_final_name", [C_TYPE], rffi.CCHARP, - threadsafe=ts_reflect, + releasegil=ts_reflect, compilation_info=backend.eci) def c_final_name(space, cpptype): return charp2str_free(space, _c_final_name(cpptype)) _c_scoped_final_name = rffi.llexternal( "cppyy_scoped_final_name", [C_TYPE], rffi.CCHARP, - threadsafe=ts_reflect, + releasegil=ts_reflect, compilation_info=backend.eci) def c_scoped_final_name(space, cpptype): return charp2str_free(space, _c_scoped_final_name(cpptype)) _c_has_complex_hierarchy = rffi.llexternal( "cppyy_has_complex_hierarchy", [C_TYPE], rffi.INT, - threadsafe=ts_reflect, + releasegil=ts_reflect, compilation_info=backend.eci) def c_has_complex_hierarchy(space, cpptype): return _c_has_complex_hierarchy(cpptype) _c_num_bases = rffi.llexternal( "cppyy_num_bases", [C_TYPE], rffi.INT, - threadsafe=ts_reflect, + releasegil=ts_reflect, compilation_info=backend.eci) def c_num_bases(space, cppclass): return _c_num_bases(cppclass.handle) _c_base_name = rffi.llexternal( "cppyy_base_name", [C_TYPE, rffi.INT], rffi.CCHARP, - threadsafe=ts_reflect, + releasegil=ts_reflect, compilation_info=backend.eci) def c_base_name(space, cppclass, base_index): return charp2str_free(space, _c_base_name(cppclass.handle, base_index)) _c_is_subtype = rffi.llexternal( "cppyy_is_subtype", [C_TYPE, C_TYPE], rffi.INT, - threadsafe=ts_reflect, + releasegil=ts_reflect, compilation_info=backend.eci, elidable_function=True) @jit.elidable_promote('2') @@ -293,7 +293,7 @@ _c_base_offset = rffi.llexternal( "cppyy_base_offset", [C_TYPE, C_TYPE, C_OBJECT, rffi.INT], rffi.SIZE_T, - threadsafe=ts_reflect, + releasegil=ts_reflect, compilation_info=backend.eci, elidable_function=True) @jit.elidable_promote('1,2,4') @@ -308,21 +308,21 @@ _c_num_methods = rffi.llexternal( "cppyy_num_methods", [C_SCOPE], rffi.INT, - threadsafe=ts_reflect, + releasegil=ts_reflect, compilation_info=backend.eci) def c_num_methods(space, cppscope): return _c_num_methods(cppscope.handle) _c_method_index_at = rffi.llexternal( "cppyy_method_index_at", [C_SCOPE, rffi.INT], C_INDEX, - threadsafe=ts_reflect, + releasegil=ts_reflect, compilation_info=backend.eci) def c_method_index_at(space, cppscope, imethod): return _c_method_index_at(cppscope.handle, imethod) _c_method_indices_from_name = rffi.llexternal( "cppyy_method_indices_from_name", [C_SCOPE, rffi.CCHARP], C_INDEX_ARRAY, - threadsafe=ts_reflect, + releasegil=ts_reflect, compilation_info=backend.eci) def c_method_indices_from_name(space, cppscope, name): indices = _c_method_indices_from_name(cppscope.handle, name) @@ -341,49 +341,49 @@ _c_method_name = rffi.llexternal( "cppyy_method_name", [C_SCOPE, C_INDEX], rffi.CCHARP, - threadsafe=ts_reflect, + releasegil=ts_reflect, compilation_info=backend.eci) def c_method_name(space, cppscope, index): return charp2str_free(space, _c_method_name(cppscope.handle, index)) _c_method_result_type = rffi.llexternal( "cppyy_method_result_type", [C_SCOPE, C_INDEX], rffi.CCHARP, - threadsafe=ts_reflect, + releasegil=ts_reflect, compilation_info=backend.eci) def c_method_result_type(space, cppscope, index): return charp2str_free(space, _c_method_result_type(cppscope.handle, index)) _c_method_num_args = rffi.llexternal( "cppyy_method_num_args", [C_SCOPE, C_INDEX], rffi.INT, - threadsafe=ts_reflect, + releasegil=ts_reflect, compilation_info=backend.eci) def c_method_num_args(space, cppscope, index): return _c_method_num_args(cppscope.handle, index) _c_method_req_args = rffi.llexternal( "cppyy_method_req_args", [C_SCOPE, C_INDEX], rffi.INT, - threadsafe=ts_reflect, + releasegil=ts_reflect, compilation_info=backend.eci) def c_method_req_args(space, cppscope, index): return _c_method_req_args(cppscope.handle, index) _c_method_arg_type = rffi.llexternal( "cppyy_method_arg_type", [C_SCOPE, C_INDEX, rffi.INT], rffi.CCHARP, - threadsafe=ts_reflect, + releasegil=ts_reflect, compilation_info=backend.eci) def c_method_arg_type(space, cppscope, index, arg_index): return charp2str_free(space, _c_method_arg_type(cppscope.handle, index, arg_index)) _c_method_arg_default = rffi.llexternal( "cppyy_method_arg_default", [C_SCOPE, C_INDEX, rffi.INT], rffi.CCHARP, - threadsafe=ts_reflect, + releasegil=ts_reflect, compilation_info=backend.eci) def c_method_arg_default(space, cppscope, index, arg_index): return charp2str_free(space, _c_method_arg_default(cppscope.handle, index, arg_index)) _c_method_signature = rffi.llexternal( "cppyy_method_signature", [C_SCOPE, C_INDEX], rffi.CCHARP, - threadsafe=ts_reflect, + releasegil=ts_reflect, compilation_info=backend.eci) def c_method_signature(space, cppscope, index): return charp2str_free(space, _c_method_signature(cppscope.handle, index)) @@ -391,19 +391,19 @@ _c_method_is_template = rffi.llexternal( "cppyy_method_is_template", [C_SCOPE, C_INDEX], rffi.INT, - threadsafe=ts_reflect, + releasegil=ts_reflect, compilation_info=backend.eci) def c_method_is_template(space, 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, + releasegil=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, + releasegil=ts_reflect, compilation_info=backend.eci) def c_template_args(space, cppscope, index): nargs = _c_method_num_template_args(cppscope.handle, index) @@ -415,14 +415,14 @@ _c_get_method = rffi.llexternal( "cppyy_get_method", [C_SCOPE, C_INDEX], C_METHOD, - threadsafe=ts_reflect, + releasegil=ts_reflect, compilation_info=backend.eci) def c_get_method(space, cppscope, index): return _c_get_method(cppscope.handle, index) _c_get_global_operator = rffi.llexternal( "cppyy_get_global_operator", [C_SCOPE, C_SCOPE, C_SCOPE, rffi.CCHARP], WLAVC_INDEX, - threadsafe=ts_reflect, + releasegil=ts_reflect, compilation_info=backend.eci) def c_get_global_operator(space, nss, lc, rc, op): if nss is not None: @@ -433,14 +433,14 @@ _c_is_constructor = rffi.llexternal( "cppyy_is_constructor", [C_TYPE, C_INDEX], rffi.INT, - threadsafe=ts_reflect, + releasegil=ts_reflect, compilation_info=backend.eci) def c_is_constructor(space, cppclass, index): return _c_is_constructor(cppclass.handle, index) _c_is_staticmethod = rffi.llexternal( "cppyy_is_staticmethod", [C_TYPE, C_INDEX], rffi.INT, - threadsafe=ts_reflect, + releasegil=ts_reflect, compilation_info=backend.eci) def c_is_staticmethod(space, cppclass, index): return _c_is_staticmethod(cppclass.handle, index) @@ -449,28 +449,28 @@ _c_num_datamembers = rffi.llexternal( "cppyy_num_datamembers", [C_SCOPE], rffi.INT, - threadsafe=ts_reflect, + releasegil=ts_reflect, compilation_info=backend.eci) def c_num_datamembers(space, cppscope): return _c_num_datamembers(cppscope.handle) _c_datamember_name = rffi.llexternal( "cppyy_datamember_name", [C_SCOPE, rffi.INT], rffi.CCHARP, - threadsafe=ts_reflect, + releasegil=ts_reflect, compilation_info=backend.eci) def c_datamember_name(space, cppscope, datamember_index): return charp2str_free(space, _c_datamember_name(cppscope.handle, datamember_index)) _c_datamember_type = rffi.llexternal( "cppyy_datamember_type", [C_SCOPE, rffi.INT], rffi.CCHARP, - threadsafe=ts_reflect, + releasegil=ts_reflect, compilation_info=backend.eci) def c_datamember_type(space, cppscope, datamember_index): return charp2str_free(space, _c_datamember_type(cppscope.handle, datamember_index)) _c_datamember_offset = rffi.llexternal( "cppyy_datamember_offset", [C_SCOPE, rffi.INT], rffi.SIZE_T, - threadsafe=ts_reflect, + releasegil=ts_reflect, compilation_info=backend.eci) def c_datamember_offset(space, cppscope, datamember_index): return _c_datamember_offset(cppscope.handle, datamember_index) @@ -478,7 +478,7 @@ _c_datamember_index = rffi.llexternal( "cppyy_datamember_index", [C_SCOPE, rffi.CCHARP], rffi.INT, - threadsafe=ts_reflect, + releasegil=ts_reflect, compilation_info=backend.eci) def c_datamember_index(space, cppscope, name): return _c_datamember_index(cppscope.handle, name) @@ -487,14 +487,14 @@ _c_is_publicdata = rffi.llexternal( "cppyy_is_publicdata", [C_SCOPE, rffi.INT], rffi.INT, - threadsafe=ts_reflect, + releasegil=ts_reflect, compilation_info=backend.eci) def c_is_publicdata(space, cppscope, datamember_index): return _c_is_publicdata(cppscope.handle, datamember_index) _c_is_staticdata = rffi.llexternal( "cppyy_is_staticdata", [C_SCOPE, rffi.INT], rffi.INT, - threadsafe=ts_reflect, + releasegil=ts_reflect, compilation_info=backend.eci) def c_is_staticdata(space, cppscope, datamember_index): return _c_is_staticdata(cppscope.handle, datamember_index) @@ -503,21 +503,21 @@ _c_strtoll = rffi.llexternal( "cppyy_strtoll", [rffi.CCHARP], rffi.LONGLONG, - threadsafe=ts_helper, + releasegil=ts_helper, compilation_info=backend.eci) def c_strtoll(space, svalue): return _c_strtoll(svalue) _c_strtoull = rffi.llexternal( "cppyy_strtoull", [rffi.CCHARP], rffi.ULONGLONG, - threadsafe=ts_helper, + releasegil=ts_helper, compilation_info=backend.eci) def c_strtoull(space, svalue): return _c_strtoull(svalue) c_free = rffi.llexternal( "cppyy_free", [rffi.VOIDP], lltype.Void, - threadsafe=ts_memory, + releasegil=ts_memory, compilation_info=backend.eci) def charp2str_free(space, charp): @@ -529,7 +529,7 @@ _c_charp2stdstring = rffi.llexternal( "cppyy_charp2stdstring", [rffi.CCHARP], C_OBJECT, - threadsafe=ts_helper, + releasegil=ts_helper, compilation_info=backend.eci) def c_charp2stdstring(space, svalue): charp = rffi.str2charp(svalue) @@ -539,14 +539,14 @@ _c_stdstring2stdstring = rffi.llexternal( "cppyy_stdstring2stdstring", [C_OBJECT], C_OBJECT, - threadsafe=ts_helper, + releasegil=ts_helper, compilation_info=backend.eci) def c_stdstring2stdstring(space, cppobject): return _c_stdstring2stdstring(cppobject) _c_assign2stdstring = rffi.llexternal( "cppyy_assign2stdstring", [C_OBJECT, rffi.CCHARP], lltype.Void, - threadsafe=ts_helper, + releasegil=ts_helper, compilation_info=backend.eci) def c_assign2stdstring(space, cppobject, svalue): charp = rffi.str2charp(svalue) @@ -555,7 +555,7 @@ _c_free_stdstring = rffi.llexternal( "cppyy_free_stdstring", [C_OBJECT], lltype.Void, - threadsafe=ts_helper, + releasegil=ts_helper, compilation_info=backend.eci) def c_free_stdstring(space, cppobject): _c_free_stdstring(cppobject) 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 @@ -60,7 +60,7 @@ _c_load_dictionary = rffi.llexternal( "cppyy_load_dictionary", [rffi.CCHARP], rdynload.DLLHANDLE, - threadsafe=False, + releasegil=False, compilation_info=eci) def c_load_dictionary(name): @@ -84,7 +84,7 @@ _ttree_Branch = rffi.llexternal( "cppyy_ttree_Branch", [rffi.VOIDP, rffi.CCHARP, rffi.CCHARP, rffi.VOIDP, rffi.INT, rffi.INT], rffi.LONG, - threadsafe=False, + releasegil=False, compilation_info=eci) @unwrap_spec(args_w='args_w') @@ -158,7 +158,7 @@ c_ttree_GetEntry = rffi.llexternal( "cppyy_ttree_GetEntry", [rffi.VOIDP, rffi.LONGLONG], rffi.LONGLONG, - threadsafe=False, + releasegil=False, compilation_info=eci) @unwrap_spec(args_w='args_w') diff --git a/pypy/module/crypt/interp_crypt.py b/pypy/module/crypt/interp_crypt.py --- a/pypy/module/crypt/interp_crypt.py +++ b/pypy/module/crypt/interp_crypt.py @@ -8,7 +8,7 @@ else: eci = ExternalCompilationInfo(libraries=['crypt']) c_crypt = rffi.llexternal('crypt', [rffi.CCHARP, rffi.CCHARP], rffi.CCHARP, - compilation_info=eci, threadsafe=False) + compilation_info=eci, releasegil=False) @unwrap_spec(word=str, salt=str) def crypt(space, word, salt): 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 @@ -356,7 +356,7 @@ XML_ParserCreateNS = expat_external( 'XML_ParserCreateNS', [rffi.CCHARP, rffi.CHAR], XML_Parser) XML_ParserFree = expat_external( - 'XML_ParserFree', [XML_Parser], lltype.Void, threadsafe=False) + 'XML_ParserFree', [XML_Parser], lltype.Void, releasegil=False) XML_SetUserData = expat_external( 'XML_SetUserData', [XML_Parser, rffi.VOIDP], lltype.Void) def XML_GetUserData(parser): 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 @@ -151,7 +151,7 @@ return rffi.llexternal(name, args, result, compilation_info=eci, calling_conv=calling_conv, - threadsafe=False) + releasegil=False) if _POSIX: cConfig.timeval.__name__ = "_timeval" 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 @@ -181,7 +181,7 @@ from rpython.jit.backend.llgraph.runner import LLGraphCPU T = rffi.CArrayPtr(rffi.TIME_T) - external = rffi.llexternal("time", [T], rffi.TIME_T, threadsafe=True) + external = rffi.llexternal("time", [T], rffi.TIME_T, releasegil=True) @jit.dont_look_inside def f(): @@ -203,7 +203,7 @@ from rpython.jit.backend.llgraph.runner import LLGraphCPU T = rffi.CArrayPtr(rffi.TIME_T) - external = rffi.llexternal("time", [T], rffi.TIME_T, threadsafe=True) + external = rffi.llexternal("time", [T], rffi.TIME_T, releasegil=True) # no jit.dont_look_inside in this test def f(): diff --git a/rpython/jit/metainterp/test/test_ajit.py b/rpython/jit/metainterp/test/test_ajit.py --- a/rpython/jit/metainterp/test/test_ajit.py +++ b/rpython/jit/metainterp/test/test_ajit.py @@ -3232,7 +3232,7 @@ py.test.skip("needs 'time'") T = rffi.CArrayPtr(rffi.TIME_T) - external = rffi.llexternal("time", [T], rffi.TIME_T, threadsafe=True) + external = rffi.llexternal("time", [T], rffi.TIME_T, releasegil=True) # Not a real lock, has all the same properties with respect to GIL # release though, so good for this test. class Lock(object): diff --git a/rpython/memory/gctransform/test/test_framework.py b/rpython/memory/gctransform/test/test_framework.py --- a/rpython/memory/gctransform/test/test_framework.py +++ b/rpython/memory/gctransform/test/test_framework.py @@ -72,14 +72,14 @@ assert not CollectAnalyzer(t).analyze_direct_call(gg) def test_cancollect_external(): - fext1 = rffi.llexternal('fext1', [], lltype.Void, threadsafe=False) + fext1 = rffi.llexternal('fext1', [], lltype.Void, releasegil=False) def g(): fext1() t = rtype(g, []) gg = graphof(t, g) assert not CollectAnalyzer(t).analyze_direct_call(gg) - fext2 = rffi.llexternal('fext2', [], lltype.Void, threadsafe=True) + fext2 = rffi.llexternal('fext2', [], lltype.Void, releasegil=True) def g(): fext2() t = rtype(g, []) @@ -88,7 +88,7 @@ S = lltype.GcStruct('S', ('x', lltype.Signed)) FUNC = lltype.Ptr(lltype.FuncType([lltype.Signed], lltype.Void)) - fext3 = rffi.llexternal('fext3', [FUNC], lltype.Void, threadsafe=False) + fext3 = rffi.llexternal('fext3', [FUNC], lltype.Void, releasegil=False) def h(x): lltype.malloc(S, zero=True) def g(): 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 @@ -481,9 +481,9 @@ socket = external('socket', [rffi.INT, rffi.INT, rffi.INT], socketfd_type) if WIN32: - socketclose = external('closesocket', [socketfd_type], rffi.INT, threadsafe=False) + socketclose = external('closesocket', [socketfd_type], rffi.INT, releasegil=False) else: - socketclose = external('close', [socketfd_type], rffi.INT, threadsafe=False) + socketclose = external('close', [socketfd_type], rffi.INT, releasegil=False) socketconnect = external('connect', [socketfd_type, sockaddr_ptr, socklen_t], rffi.INT) @@ -494,10 +494,10 @@ getnameinfo = external('getnameinfo', [sockaddr_ptr, socklen_t, CCHARP, size_t, CCHARP, size_t, rffi.INT], rffi.INT) -htonl = external('htonl', [rffi.UINT], rffi.UINT, threadsafe=False) -htons = external('htons', [rffi.USHORT], rffi.USHORT, threadsafe=False) -ntohl = external('ntohl', [rffi.UINT], rffi.UINT, threadsafe=False) -ntohs = external('ntohs', [rffi.USHORT], rffi.USHORT, threadsafe=False) +htonl = external('htonl', [rffi.UINT], rffi.UINT, releasegil=False) +htons = external('htons', [rffi.USHORT], rffi.USHORT, releasegil=False) +ntohl = external('ntohl', [rffi.UINT], rffi.UINT, releasegil=False) +ntohs = external('ntohs', [rffi.USHORT], rffi.USHORT, releasegil=False) if _POSIX: inet_aton = external('inet_aton', [CCHARP, lltype.Ptr(in_addr)], diff --git a/rpython/rlib/rdynload.py b/rpython/rlib/rdynload.py --- a/rpython/rlib/rdynload.py +++ b/rpython/rlib/rdynload.py @@ -68,7 +68,7 @@ if not _WIN32: c_dlopen = external('dlopen', [rffi.CCHARP, rffi.INT], rffi.VOIDP) - c_dlclose = external('dlclose', [rffi.VOIDP], rffi.INT, threadsafe=False) + c_dlclose = external('dlclose', [rffi.VOIDP], rffi.INT, releasegil=False) c_dlerror = external('dlerror', [], rffi.CCHARP) c_dlsym = external('dlsym', [rffi.VOIDP, rffi.CCHARP], rffi.VOIDP) diff --git a/rpython/rlib/rmmap.py b/rpython/rlib/rmmap.py --- a/rpython/rlib/rmmap.py +++ b/rpython/rlib/rmmap.py @@ -113,7 +113,7 @@ **kwargs) safe = rffi.llexternal(name, args, result, compilation_info=CConfig._compilation_info_, - sandboxsafe=True, threadsafe=False, + sandboxsafe=True, releasegil=False, **kwargs) return unsafe, safe @@ -195,7 +195,7 @@ CreateFileMapping = winexternal('CreateFileMappingA', [HANDLE, rwin32.LPSECURITY_ATTRIBUTES, DWORD, DWORD, DWORD, LPCSTR], HANDLE) MapViewOfFile = winexternal('MapViewOfFile', [HANDLE, DWORD, DWORD, DWORD, SIZE_T], LPCSTR)##!!LPVOID) UnmapViewOfFile = winexternal('UnmapViewOfFile', [LPCSTR], BOOL, - threadsafe=False) + releasegil=False) FlushViewOfFile = winexternal('FlushViewOfFile', [LPCSTR, SIZE_T], BOOL) SetFilePointer = winexternal('SetFilePointer', [HANDLE, LONG, PLONG, DWORD], DWORD) SetEndOfFile = winexternal('SetEndOfFile', [HANDLE], BOOL) diff --git a/rpython/rlib/ropenssl.py b/rpython/rlib/ropenssl.py --- a/rpython/rlib/ropenssl.py +++ b/rpython/rlib/ropenssl.py @@ -242,7 +242,7 @@ ssl_external('X509_NAME_ENTRY_get_object', [X509_NAME_ENTRY], ASN1_OBJECT) ssl_external('X509_NAME_ENTRY_get_data', [X509_NAME_ENTRY], ASN1_STRING) ssl_external('i2d_X509', [X509, rffi.CCHARPP], rffi.INT) -ssl_external('X509_free', [X509], lltype.Void, threadsafe=False) +ssl_external('X509_free', [X509], lltype.Void, releasegil=False) ssl_external('X509_get_notBefore', [X509], ASN1_TIME, macro=True) ssl_external('X509_get_notAfter', [X509], ASN1_TIME, macro=True) ssl_external('X509_get_serialNumber', [X509], ASN1_INTEGER) @@ -282,10 +282,10 @@ ssl_external('ERR_error_string', [rffi.ULONG, rffi.CCHARP], rffi.CCHARP) ssl_external('ERR_clear_error', [], lltype.Void) -# 'threadsafe=False' here indicates that this function will be called +# 'releasegil=False' here indicates that this function will be called # with the GIL held, and so is allowed to run in a RPython __del__ method. -ssl_external('SSL_free', [SSL], lltype.Void, threadsafe=False) -ssl_external('SSL_CTX_free', [SSL_CTX], lltype.Void, threadsafe=False) +ssl_external('SSL_free', [SSL], lltype.Void, releasegil=False) +ssl_external('SSL_CTX_free', [SSL_CTX], lltype.Void, releasegil=False) ssl_external('CRYPTO_free', [rffi.VOIDP], lltype.Void) libssl_OPENSSL_free = libssl_CRYPTO_free @@ -325,7 +325,7 @@ EVP_MD_CTX_copy = external( 'EVP_MD_CTX_copy', [EVP_MD_CTX, EVP_MD_CTX], rffi.INT) EVP_MD_CTX_cleanup = external( - 'EVP_MD_CTX_cleanup', [EVP_MD_CTX], rffi.INT, threadsafe=False) + 'EVP_MD_CTX_cleanup', [EVP_MD_CTX], rffi.INT, releasegil=False) OBJ_NAME_CALLBACK = lltype.Ptr(lltype.FuncType( [OBJ_NAME, rffi.VOIDP], lltype.Void)) diff --git a/rpython/rlib/rsignal.py b/rpython/rlib/rsignal.py --- a/rpython/rlib/rsignal.py +++ b/rpython/rlib/rsignal.py @@ -77,11 +77,11 @@ pypysig_setflag = external('pypysig_setflag', [rffi.INT], lltype.Void) pypysig_reinstall = external('pypysig_reinstall', [rffi.INT], lltype.Void) pypysig_set_wakeup_fd = external('pypysig_set_wakeup_fd', [rffi.INT], rffi.INT) -pypysig_poll = external('pypysig_poll', [], rffi.INT, threadsafe=False) +pypysig_poll = external('pypysig_poll', [], rffi.INT, releasegil=False) # don't bother releasing the GIL around a call to pypysig_poll: it's # pointless and a performance issue pypysig_pushback = external('pypysig_pushback', [rffi.INT], lltype.Void, - threadsafe=False) + releasegil=False) # don't use rffi.LONGP because the JIT doesn't support raw arrays so far struct_name = 'pypysig_long_struct' @@ -93,7 +93,7 @@ lltype.Ptr(LONG_STRUCT), _nowrapper=True, elidable_function=True) c_alarm = external('alarm', [rffi.INT], rffi.INT) -c_pause = external('pause', [], rffi.INT, threadsafe=True) +c_pause = external('pause', [], rffi.INT, releasegil=True) c_siginterrupt = external('siginterrupt', [rffi.INT, rffi.INT], rffi.INT) if sys.platform != 'win32': diff --git a/rpython/rlib/rthread.py b/rpython/rlib/rthread.py --- a/rpython/rlib/rthread.py +++ b/rpython/rlib/rthread.py @@ -44,7 +44,7 @@ CALLBACK = lltype.Ptr(lltype.FuncType([], lltype.Void)) c_thread_start = llexternal('RPyThreadStart', [CALLBACK], rffi.LONG, _callable=_emulated_start_new_thread, - threadsafe=True) # release the GIL, but most + releasegil=True) # release the GIL, but most # importantly, reacquire it # around the callback c_thread_get_ident = llexternal('RPyThreadGetIdent', [], rffi.LONG, @@ -54,19 +54,19 @@ compilation_info=eci) TLOCKP_SIZE = rffi_platform.sizeof('struct RPyOpaque_ThreadLock', eci) c_thread_lock_init = llexternal('RPyThreadLockInit', [TLOCKP], rffi.INT, - threadsafe=False) # may add in a global list + releasegil=False) # may add in a global list c_thread_lock_dealloc_NOAUTO = llexternal('RPyOpaqueDealloc_ThreadLock', [TLOCKP], lltype.Void, _nowrapper=True) c_thread_acquirelock = llexternal('RPyThreadAcquireLock', [TLOCKP, rffi.INT], rffi.INT, - threadsafe=True) # release the GIL + releasegil=True) # release the GIL c_thread_acquirelock_timed = llexternal('RPyThreadAcquireLockTimed', [TLOCKP, rffi.LONGLONG, rffi.INT], rffi.INT, - threadsafe=True) # release the GIL + releasegil=True) # release the GIL c_thread_releaselock = llexternal('RPyThreadReleaseLock', [TLOCKP], lltype.Void, - threadsafe=True) # release the GIL + releasegil=True) # release the GIL # another set of functions, this time in versions that don't cause the # GIL to be released. To use to handle the GIL lock itself. diff --git a/rpython/rlib/rwin32.py b/rpython/rlib/rwin32.py --- a/rpython/rlib/rwin32.py +++ b/rpython/rlib/rwin32.py @@ -118,7 +118,7 @@ INVALID_HANDLE_VALUE = rffi.cast(HANDLE, -1) PFILETIME = rffi.CArrayPtr(FILETIME) - _GetLastError = winexternal('GetLastError', [], DWORD, threadsafe=False) + _GetLastError = winexternal('GetLastError', [], DWORD, releasegil=False) _SetLastError = winexternal('SetLastError', [DWORD], lltype.Void) def GetLastError(): @@ -134,10 +134,10 @@ GetProcAddress = winexternal('GetProcAddress', [HMODULE, rffi.CCHARP], rffi.VOIDP) - FreeLibrary = winexternal('FreeLibrary', [HMODULE], BOOL, threadsafe=False) + FreeLibrary = winexternal('FreeLibrary', [HMODULE], BOOL, releasegil=False) LocalFree = winexternal('LocalFree', [HLOCAL], DWORD) - CloseHandle = winexternal('CloseHandle', [HANDLE], BOOL, threadsafe=False) + CloseHandle = winexternal('CloseHandle', [HANDLE], BOOL, releasegil=False) FormatMessage = winexternal( 'FormatMessageA', diff --git a/rpython/rlib/rzlib.py b/rpython/rlib/rzlib.py --- a/rpython/rlib/rzlib.py +++ b/rpython/rlib/rzlib.py @@ -134,7 +134,7 @@ _deflate = zlib_external('deflate', [z_stream_p, rffi.INT], rffi.INT) _deflateEnd = zlib_external('deflateEnd', [z_stream_p], rffi.INT, - threadsafe=False) + releasegil=False) def _deflateInit2(stream, level, method, wbits, memlevel, strategy): size = rffi.sizeof(z_stream) @@ -153,7 +153,7 @@ _inflate = zlib_external('inflate', [z_stream_p, rffi.INT], rffi.INT) _inflateEnd = zlib_external('inflateEnd', [z_stream_p], rffi.INT, - threadsafe=False) + releasegil=False) def _inflateInit2(stream, wbits): size = rffi.sizeof(z_stream) diff --git a/rpython/rtyper/lltypesystem/rffi.py b/rpython/rtyper/lltypesystem/rffi.py --- a/rpython/rtyper/lltypesystem/rffi.py +++ b/rpython/rtyper/lltypesystem/rffi.py @@ -60,7 +60,7 @@ def llexternal(name, args, result, _callable=None, compilation_info=ExternalCompilationInfo(), - sandboxsafe=False, threadsafe='auto', + sandboxsafe=False, releasegil='auto', _nowrapper=False, calling_conv='c', elidable_function=False, macro=None, random_effects_on_gcobjs='auto'): @@ -77,7 +77,7 @@ as constant RPython functions. We don't support yet C functions that invoke callbacks passed otherwise (e.g. set by a previous C call). - threadsafe: whether it's ok to release the GIL around the call. + releasegil: whether it's ok to release the GIL around the call. Default is yes, unless sandboxsafe is set, in which case we consider that the function is really short-running and don't bother releasing the GIL. An explicit True or False @@ -107,10 +107,10 @@ else: callbackholder = None - if threadsafe in (False, True): + if releasegil in (False, True): # invoke the around-handlers, which release the GIL, if and only if # the C function is thread-safe. - invoke_around_handlers = threadsafe + invoke_around_handlers = releasegil else: # default case: # invoke the around-handlers only for "not too small" external calls; @@ -1132,11 +1132,3 @@ keep_unicodebuffer_alive_until_here(self.raw, self.gc_buf) def str(self, length): return unicode_from_buffer(self.raw, self.gc_buf, self.size, length) - -# You would have to have a *huge* amount of data for this to block long enough -# to be worth it to release the GIL. -c_memcpy = llexternal("memcpy", - [VOIDP, VOIDP, SIZE_T], - lltype.Void, - threadsafe=False -) 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 @@ -379,7 +379,7 @@ @registering_if(os, "getlogin", condition=not _WIN32) def register_os_getlogin(self): - os_getlogin = self.llexternal('getlogin', [], rffi.CCHARP, threadsafe=False) + os_getlogin = self.llexternal('getlogin', [], rffi.CCHARP, releasegil=False) def getlogin_llimpl(): result = os_getlogin() @@ -681,7 +681,7 @@ @registering_if(os, 'getpid') def register_os_getpid(self): - return self.extdef_for_os_function_returning_int('getpid', threadsafe=False) + return self.extdef_for_os_function_returning_int('getpid', releasegil=False) @registering_if(os, 'getgid') def register_os_getgid(self): @@ -882,7 +882,7 @@ @registering(os.close) def register_os_close(self): os_close = self.llexternal(underscore_on_windows+'close', [rffi.INT], - rffi.INT, threadsafe=False) + rffi.INT, releasegil=False) def close_llimpl(fd): rposix.validate_fd(fd) @@ -1323,7 +1323,7 @@ @registering(os.strerror) def register_os_strerror(self): - os_strerror = self.llexternal('strerror', [rffi.INT], rffi.CCHARP, threadsafe=False) + os_strerror = self.llexternal('strerror', [rffi.INT], rffi.CCHARP, releasegil=False) def strerror_llimpl(errnum): res = os_strerror(rffi.cast(rffi.INT, errnum)) @@ -1738,7 +1738,7 @@ @registering_if(os, 'ttyname') def register_os_ttyname(self): - os_ttyname = self.llexternal('ttyname', [lltype.Signed], rffi.CCHARP, threadsafe=False) + os_ttyname = self.llexternal('ttyname', [lltype.Signed], rffi.CCHARP, releasegil=False) def ttyname_llimpl(fd): l_name = os_ttyname(fd) diff --git a/rpython/rtyper/module/ll_os_environ.py b/rpython/rtyper/module/ll_os_environ.py --- a/rpython/rtyper/module/ll_os_environ.py +++ b/rpython/rtyper/module/ll_os_environ.py @@ -116,11 +116,11 @@ just_a_placeholder os_getenv = rffi.llexternal('getenv', [rffi.CCHARP], rffi.CCHARP, - threadsafe=False) + releasegil=False) os_putenv = rffi.llexternal('putenv', [rffi.CCHARP], rffi.INT) if _WIN32: _wgetenv = rffi.llexternal('_wgetenv', [rffi.CWCHARP], rffi.CWCHARP, - compilation_info=eci, threadsafe=False) + compilation_info=eci, releasegil=False) _wputenv = rffi.llexternal('_wputenv', [rffi.CWCHARP], rffi.INT, compilation_info=eci) diff --git a/rpython/rtyper/module/ll_time.py b/rpython/rtyper/module/ll_time.py --- a/rpython/rtyper/module/ll_time.py +++ b/rpython/rtyper/module/ll_time.py @@ -81,11 +81,11 @@ if self.GETTIMEOFDAY_NO_TZ: c_gettimeofday = self.llexternal('gettimeofday', [self.TIMEVALP], rffi.INT, - _nowrapper=True, threadsafe=False) + _nowrapper=True, releasegil=False) else: c_gettimeofday = self.llexternal('gettimeofday', [self.TIMEVALP, rffi.VOIDP], rffi.INT, - _nowrapper=True, threadsafe=False) + _nowrapper=True, releasegil=False) else: c_gettimeofday = None @@ -93,12 +93,12 @@ self.configure(CConfigForFTime) c_ftime = self.llexternal(FTIME, [lltype.Ptr(self.TIMEB)], lltype.Void, - _nowrapper=True, threadsafe=False) + _nowrapper=True, releasegil=False) else: c_ftime = None # to not confuse the flow space c_time = self.llexternal('time', [rffi.VOIDP], rffi.TIME_T, - _nowrapper=True, threadsafe=False) + _nowrapper=True, releasegil=False) def time_time_llimpl(): void = lltype.nullptr(rffi.VOIDP.TO) @@ -136,10 +136,10 @@ A = lltype.FixedSizeArray(lltype.SignedLongLong, 1) QueryPerformanceCounter = self.llexternal( 'QueryPerformanceCounter', [lltype.Ptr(A)], lltype.Void, - threadsafe=False) + releasegil=False) QueryPerformanceFrequency = self.llexternal( 'QueryPerformanceFrequency', [lltype.Ptr(A)], rffi.INT, - threadsafe=False) + releasegil=False) class State(object): pass state = State() @@ -162,7 +162,7 @@ c_getrusage = self.llexternal('getrusage', [rffi.INT, lltype.Ptr(RUSAGE)], lltype.Void, - threadsafe=False) + releasegil=False) def time_clock_llimpl(): a = lltype.malloc(RUSAGE, flavor='raw') c_getrusage(RUSAGE_SELF, a) diff --git a/rpython/translator/backendopt/test/test_gilanalysis.py b/rpython/translator/backendopt/test/test_gilanalysis.py --- a/rpython/translator/backendopt/test/test_gilanalysis.py +++ b/rpython/translator/backendopt/test/test_gilanalysis.py @@ -7,16 +7,16 @@ from rpython.translator.translator import graphof def test_canrelease_external(): - for ths in ['auto', True, False]: + for rel in ['auto', True, False]: for sbxs in [True, False]: fext = rffi.llexternal('fext2', [], lltype.Void, - threadsafe=ths, sandboxsafe=sbxs) + releasegil=rel, sandboxsafe=sbxs) def g(): fext() t = rtype(g, []) gg = graphof(t, g) - releases = (ths == 'auto' and not sbxs) or ths is True + releases = (rel == 'auto' and not sbxs) or rel is True assert releases == gilanalysis.GilAnalyzer(t).analyze_direct_call(gg) def test_canrelease_instantiate(): @@ -58,7 +58,7 @@ def test_no_release_gil_detect(gc="minimark"): from rpython.rlib import rgc - fext1 = rffi.llexternal('fext1', [], lltype.Void, threadsafe=True) + fext1 = rffi.llexternal('fext1', [], lltype.Void, releasegil=True) @rgc.no_release_gil def g(): fext1() @@ -74,7 +74,3 @@ f = py.test.raises(Exception, gilanalysis.analyze, t.graphs, t) expected = "'no_release_gil' function can release the GIL: Author: Armin Rigo Branch: Changeset: r66955:17d998fa0139 Date: 2013-09-15 17:23 +0200 http://bitbucket.org/pypy/pypy/changeset/17d998fa0139/ Log: Move the recent first argument 'logger' of compile_loop() and compile_bridge() --- which is usually None from tests --- into a keyword argument that default to None. 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 @@ -56,13 +56,13 @@ def finish_once(self): self.assembler.finish_once() - def compile_loop(self, logger, inputargs, operations, looptoken, - log=True, name=''): + def compile_loop(self, inputargs, operations, looptoken, + log=True, name='', logger=None): return self.assembler.assemble_loop(logger, name, inputargs, operations, looptoken, log=log) - def compile_bridge(self, logger, faildescr, inputargs, operations, - original_loop_token, log=True): + def compile_bridge(self, faildescr, inputargs, operations, + original_loop_token, log=True, logger=None): clt = original_loop_token.compiled_loop_token clt.compiling_a_bridge() return self.assembler.assemble_bridge(logger, faildescr, inputargs, 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 @@ -40,7 +40,7 @@ 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(None, inputargs, operations, looptoken) + cpu.compile_loop(inputargs, operations, looptoken) args = [-12 , -26 , -19 , 7 , -5 , -24 , -37 , 62 , 9 , 12] deadframe = cpu.execute_token(looptoken, *args) assert cpu.get_int_value(deadframe, 0) == 0 @@ -92,7 +92,7 @@ operations[9].setfailargs([v15, v7, v10, v18, v4, v17, v1]) operations[-1].setfailargs([v7, v1, v2]) looptoken = JitCellToken() - cpu.compile_loop(None, inputargs, operations, looptoken) + cpu.compile_loop(inputargs, operations, looptoken) args = [16 , 5 , 5 , 16 , 46 , 6 , 63 , 39 , 78 , 0] deadframe = cpu.execute_token(looptoken, *args) assert cpu.get_int_value(deadframe, 0) == 105 @@ -136,7 +136,7 @@ operations[-1].setfailargs([v5, v2, v1, v10, v3, v8, v4, v6]) looptoken = JitCellToken() - cpu.compile_loop(None, inputargs, operations, looptoken) + cpu.compile_loop(inputargs, operations, looptoken) args = [-5 , 24 , 46 , -15 , 13 , -8 , 0 , -6 , 6 , 6] deadframe = cpu.execute_token(looptoken, *args) assert cpu.get_latest_descr(deadframe).identifier == 2 @@ -179,7 +179,7 @@ operations[5].setfailargs([]) operations[-1].setfailargs([v8, v2, v6, v5, v7, v1, v10]) looptoken = JitCellToken() - cpu.compile_loop(None, inputargs, operations, looptoken) + cpu.compile_loop(inputargs, operations, looptoken) args = [19 , -3 , -58 , -7 , 12 , 22 , -54 , -29 , -19 , -64] deadframe = cpu.execute_token(looptoken, *args) assert cpu.get_int_value(deadframe, 0) == -29 @@ -223,7 +223,7 @@ looptoken = JitCellToken() operations[5].setfailargs([]) operations[-1].setfailargs([v1, v4, v10, v8, v7, v3]) - cpu.compile_loop(None, inputargs, operations, looptoken) + cpu.compile_loop(inputargs, operations, looptoken) args = [1073741824 , 95 , -16 , 5 , 92 , 12 , 32 , 17 , 37 , -63] deadframe = cpu.execute_token(looptoken, *args) assert cpu.get_int_value(deadframe, 0) == 1073741824 @@ -280,7 +280,7 @@ 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(None, inputargs, operations, looptoken) + cpu.compile_loop(inputargs, operations, looptoken) deadframe = cpu.execute_token(looptoken, *args) assert cpu.get_latest_descr(deadframe).identifier == 3 assert cpu.get_int_value(deadframe, 0) == 12 @@ -328,7 +328,7 @@ operations[8].setfailargs([v5, v9]) operations[-1].setfailargs([v4, v10, v6, v5, v9, v7]) looptoken = JitCellToken() - cpu.compile_loop(None, inputargs, operations, looptoken) + cpu.compile_loop(inputargs, operations, looptoken) args = [-8 , 0 , 62 , 35 , 16 , 9 , 30 , 581610154 , -1 , 738197503] deadframe = cpu.execute_token(looptoken, *args) assert cpu.get_latest_descr(deadframe).identifier == 2 @@ -378,7 +378,7 @@ operations[-2].setfailargs([v9, v4, v10, v11, v14]) operations[-1].setfailargs([v10, v8, v1, v6, v4]) looptoken = JitCellToken() - cpu.compile_loop(None, inputargs, operations, looptoken) + cpu.compile_loop(inputargs, operations, looptoken) args = [-39 , -18 , 1588243114 , -9 , -4 , 1252698794 , 0 , 715827882 , -15 , 536870912] deadframe = cpu.execute_token(looptoken, *args) assert cpu.get_latest_descr(deadframe).identifier == 1 @@ -433,7 +433,7 @@ operations[9].setfailargs([v5, v7, v12, v14, v2, v13, v8]) operations[-1].setfailargs([v1, v2, v9]) looptoken = JitCellToken() - cpu.compile_loop(None, inputargs, operations, looptoken) + cpu.compile_loop(inputargs, operations, looptoken) args = [0 , -2 , 24 , 1 , -4 , 13 , -95 , 33 , 2 , -44] deadframe = cpu.execute_token(looptoken, *args) assert cpu.get_latest_descr(deadframe).identifier == 3 @@ -475,7 +475,7 @@ 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(None, inputargs, operations, looptoken) + cpu.compile_loop(inputargs, operations, looptoken) args = [3 , -5 , 1431655765 , 47 , 12 , 1789569706 , 15 , 939524096 , 16 , -43] deadframe = cpu.execute_token(looptoken, *args) assert cpu.get_latest_descr(deadframe).identifier == 1 @@ -524,7 +524,7 @@ operations[-1].setfailargs([v2, v3, v5, v7, v10, v8, v9]) operations[4].setfailargs([v14]) looptoken = JitCellToken() - cpu.compile_loop(None, inputargs, operations, looptoken) + cpu.compile_loop(inputargs, operations, looptoken) args = [14 , -20 , 18 , -2058005163 , 6 , 1 , -16 , 11 , 0 , 19] deadframe = cpu.execute_token(looptoken, *args) assert cpu.get_latest_descr(deadframe).identifier == 1 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 @@ -24,7 +24,7 @@ cpu = CPU(None, None) cpu.setup_once() looptoken = JitCellToken() - cpu.compile_loop(None, inputargs, operations, looptoken) + cpu.compile_loop(inputargs, operations, looptoken) deadframe = cpu.execute_token(looptoken, 9) assert cpu.get_int_value(deadframe, 0) == (9 >> 3) assert cpu.get_int_value(deadframe, 1) == (~18) @@ -48,7 +48,7 @@ cpu = CPU(None, None) cpu.setup_once() looptoken = JitCellToken() - cpu.compile_loop(None, inputargs, operations, looptoken) + cpu.compile_loop(inputargs, operations, looptoken) deadframe = cpu.execute_token(looptoken, -10) assert cpu.get_int_value(deadframe, 0) == 0 assert cpu.get_int_value(deadframe, 1) == -1000 @@ -145,7 +145,7 @@ cpu = CPU(None, None) cpu.setup_once() looptoken = JitCellToken() - cpu.compile_loop(None, inputargs, operations, looptoken) + cpu.compile_loop(inputargs, operations, looptoken) args = [-13 , 10 , 10 , 8 , -8 , -16 , -18 , 46 , -12 , 26] deadframe = cpu.execute_token(looptoken, *args) assert cpu.get_int_value(deadframe, 0) == 0 @@ -252,7 +252,7 @@ cpu = CPU(None, None) cpu.setup_once() looptoken = JitCellToken() - cpu.compile_loop(None, inputargs, operations, looptoken) + cpu.compile_loop(inputargs, operations, looptoken) args = [17 , -20 , -6 , 6 , 1 , 13 , 13 , 9 , 49 , 8] deadframe = cpu.execute_token(looptoken, *args) assert cpu.get_int_value(deadframe, 0) == 0 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 @@ -75,7 +75,7 @@ ResOperation(rop.FINISH, [inp[1]], None, descr=BasicFinalDescr(1)), ] operations[-2].setfailargs(out) - cpu.compile_loop(None, inp, operations, looptoken) + cpu.compile_loop(inp, operations, looptoken) args = [i for i in range(1, 15)] deadframe = self.cpu.execute_token(looptoken, *args) output = [self.cpu.get_int_value(deadframe, i - 1) for i in range(1, 15)] @@ -117,9 +117,9 @@ i1 = int_sub(i0, 1) finish(i1) ''') - self.cpu.compile_loop(None, loop2.inputargs, loop2.operations, lt2) - self.cpu.compile_loop(None, loop3.inputargs, loop3.operations, lt3) - self.cpu.compile_loop(None, loop1.inputargs, loop1.operations, lt1) + self.cpu.compile_loop(loop2.inputargs, loop2.operations, lt2) + self.cpu.compile_loop(loop3.inputargs, loop3.operations, lt3) + self.cpu.compile_loop(loop1.inputargs, loop1.operations, lt1) df = self.cpu.execute_token(lt1, 10) assert self.cpu.get_int_value(df, 0) == 7 @@ -214,7 +214,7 @@ ops = "".join(ops) loop = parse(ops) looptoken = JitCellToken() - self.cpu.compile_loop(None, loop.inputargs, loop.operations, looptoken) + self.cpu.compile_loop(loop.inputargs, loop.operations, looptoken) ARGS = [lltype.Signed] * numargs RES = lltype.Signed args = [i+1 for i in range(numargs)] @@ -246,7 +246,7 @@ try: self.cpu.assembler.set_debug(True) looptoken = JitCellToken() - self.cpu.compile_loop(None, ops.inputargs, ops.operations, looptoken) + self.cpu.compile_loop(ops.inputargs, ops.operations, looptoken) self.cpu.execute_token(looptoken, 0) # check debugging info struct = self.cpu.assembler.loop_run_counters[0] @@ -280,7 +280,7 @@ faildescr = BasicFailDescr(2) loop = parse(ops, self.cpu, namespace=locals()) looptoken = JitCellToken() - info = self.cpu.compile_loop(None, loop.inputargs, loop.operations, looptoken) + info = self.cpu.compile_loop(loop.inputargs, loop.operations, looptoken) ops2 = """ [i0, f1] i1 = same_as(i0) @@ -293,7 +293,7 @@ """ loop2 = parse(ops2, self.cpu, namespace=locals()) looptoken2 = JitCellToken() - info = self.cpu.compile_loop(None, loop2.inputargs, loop2.operations, looptoken2) + info = self.cpu.compile_loop(loop2.inputargs, loop2.operations, looptoken2) deadframe = self.cpu.execute_token(looptoken, -9, longlong.getfloatstorage(-13.5)) res = longlong.getrealfloat(self.cpu.get_float_value(deadframe, 0)) 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 @@ -183,8 +183,8 @@ self.stats = stats or MiniStats() self.vinfo_for_tests = kwds.get('vinfo_for_tests', None) - def compile_loop(self, logger, inputargs, operations, looptoken, log=True, - name=''): + def compile_loop(self, inputargs, operations, looptoken, log=True, + name='', logger=None): clt = model.CompiledLoopToken(self, looptoken.number) looptoken.compiled_loop_token = clt lltrace = LLTrace(inputargs, operations) @@ -192,8 +192,8 @@ clt._llgraph_alltraces = [lltrace] self._record_labels(lltrace) - def compile_bridge(self, logger, faildescr, inputargs, operations, - original_loop_token, log=True): + def compile_bridge(self, faildescr, inputargs, operations, + original_loop_token, log=True, logger=None): clt = original_loop_token.compiled_loop_token clt.compiling_a_bridge() lltrace = LLTrace(inputargs, operations) 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 @@ -676,7 +676,7 @@ 'checkdescr': checkdescr, 'fielddescr': cpu.fielddescrof(S, 'x')}) token = JitCellToken() - cpu.compile_loop(None, loop.inputargs, loop.operations, token) + cpu.compile_loop(loop.inputargs, loop.operations, token) p0 = lltype.malloc(S, zero=True) p1 = lltype.malloc(S) p2 = lltype.malloc(S) @@ -715,7 +715,7 @@ 'calldescr': checkdescr, }) token = JitCellToken() - cpu.compile_loop(None, loop.inputargs, loop.operations, token) + cpu.compile_loop(loop.inputargs, loop.operations, token) S = self.S s = lltype.malloc(S) cpu.execute_token(token, 1, s) @@ -743,7 +743,7 @@ token = JitCellToken() cpu.gc_ll_descr.init_nursery(20) cpu.setup_once() - cpu.compile_loop(None, loop.inputargs, loop.operations, token) + cpu.compile_loop(loop.inputargs, loop.operations, token) arg = longlong.getfloatstorage(2.3) frame = cpu.execute_token(token, arg) ofs = cpu.get_baseofs_of_frame_field() @@ -770,7 +770,7 @@ cpu.gc_ll_descr.collections = [[0, sizeof.size]] cpu.gc_ll_descr.init_nursery(2 * sizeof.size) cpu.setup_once() - cpu.compile_loop(None, loop.inputargs, loop.operations, token) + cpu.compile_loop(loop.inputargs, loop.operations, token) frame = cpu.execute_token(token) # now we should be able to track everything from the frame frame = lltype.cast_opaque_ptr(JITFRAMEPTR, frame) @@ -821,7 +821,7 @@ token = JitCellToken() cpu.gc_ll_descr.init_nursery(100) cpu.setup_once() - cpu.compile_loop(None, loop.inputargs, loop.operations, token) + cpu.compile_loop(loop.inputargs, loop.operations, token) args = [lltype.nullptr(llmemory.GCREF.TO) for i in range(7)] frame = cpu.execute_token(token, 1, *args) frame = rffi.cast(JITFRAMEPTR, frame) @@ -867,7 +867,7 @@ token = JitCellToken() cpu.gc_ll_descr.init_nursery(100) cpu.setup_once() - cpu.compile_loop(None, loop.inputargs, loop.operations, token) + cpu.compile_loop(loop.inputargs, loop.operations, token) frame = lltype.cast_opaque_ptr(JITFRAMEPTR, cpu.execute_token(token, 1, a)) @@ -911,7 +911,7 @@ token = JitCellToken() cpu.gc_ll_descr.init_nursery(100) cpu.setup_once() - cpu.compile_loop(None, loop.inputargs, loop.operations, token) + cpu.compile_loop(loop.inputargs, loop.operations, token) frame = lltype.cast_opaque_ptr(JITFRAMEPTR, cpu.execute_token(token, 1, a)) assert getmap(frame).count('1') == 4 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 @@ -97,7 +97,7 @@ loop = self.parse(ops, namespace=namespace) self.loop = loop looptoken = JitCellToken() - self.cpu.compile_loop(None, loop.inputargs, loop.operations, looptoken) + self.cpu.compile_loop(loop.inputargs, loop.operations, looptoken) arguments = [] for arg in args: if isinstance(arg, int): @@ -147,7 +147,7 @@ assert ([box.type for box in bridge.inputargs] == [box.type for box in guard_op.getfailargs()]) faildescr = guard_op.getdescr() - self.cpu.compile_bridge(None, faildescr, bridge.inputargs, + self.cpu.compile_bridge(faildescr, bridge.inputargs, bridge.operations, loop._jitcelltoken) return bridge diff --git a/rpython/jit/backend/llsupport/test/test_runner.py b/rpython/jit/backend/llsupport/test/test_runner.py --- a/rpython/jit/backend/llsupport/test/test_runner.py +++ b/rpython/jit/backend/llsupport/test/test_runner.py @@ -14,7 +14,7 @@ def set_debug(flag): pass - def compile_loop(self, logger, inputargs, operations, looptoken): + def compile_loop(self, inputargs, operations, looptoken): py.test.skip("llsupport test: cannot compile operations") 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 @@ -51,30 +51,21 @@ """ return False - def compile_loop(self, logger, inputargs, operations, looptoken, - log=True, name=''): + def compile_loop(self, inputargs, operations, looptoken, + log=True, name='', logger=None): """Assemble the given loop. Should create and attach a fresh CompiledLoopToken to looptoken.compiled_loop_token and stick extra attributes on it to point to the compiled loop in assembler. - - Optionally, return a ``ops_offset`` dictionary, which maps each operation - to its offset in the compiled code. The ``ops_offset`` dictionary is then - used by the operation logger to print the offsets in the log. The - offset representing the end of the last operation is stored in - ``ops_offset[None]``: note that this might not coincide with the end of - the loop, because usually in the loop footer there is code which does - not belong to any particular operation. + Returns either None or an instance of rpython.rlib.jit.AsmInfo. """ raise NotImplementedError - def compile_bridge(self, logger, faildescr, inputargs, operations, - original_loop_token, log=True): + def compile_bridge(self, faildescr, inputargs, operations, + original_loop_token, log=True, logger=None): """Assemble the bridge. The FailDescr is the descr of the original guard that failed. - - Optionally, return a ``ops_offset`` dictionary. See the docstring of - ``compiled_loop`` for more information about it. + Returns either None or an instance of rpython.rlib.jit.AsmInfo. """ raise NotImplementedError 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 @@ -105,7 +105,7 @@ loop = parse(ops, namespace=locals()) looptoken = JitCellToken() - self.cpu.compile_loop(None, loop.inputargs, loop.operations, looptoken) + self.cpu.compile_loop(loop.inputargs, loop.operations, looptoken) argvals, expected_result = self._prepare_args(args, floats, ints) deadframe = self.cpu.execute_token(looptoken, *argvals) @@ -249,7 +249,7 @@ called_looptoken = JitCellToken() called_looptoken.outermost_jitdriver_sd = FakeJitDriverSD() done_descr = called_loop.operations[-1].getdescr() - self.cpu.compile_loop(None, called_loop.inputargs, called_loop.operations, called_looptoken) + self.cpu.compile_loop(called_loop.inputargs, called_loop.operations, called_looptoken) argvals, expected_result = self._prepare_args(args, floats, ints) deadframe = cpu.execute_token(called_looptoken, *argvals) @@ -278,7 +278,7 @@ self.cpu.done_with_this_frame_descr_float = done_descr try: othertoken = JitCellToken() - self.cpu.compile_loop(None, loop.inputargs, loop.operations, othertoken) + self.cpu.compile_loop(loop.inputargs, loop.operations, othertoken) # prepare call to called_loop argvals, _ = self._prepare_args(args, floats, ints) @@ -424,7 +424,7 @@ loop = parse(ops, namespace=locals()) looptoken = JitCellToken() - self.cpu.compile_loop(None, loop.inputargs, loop.operations, looptoken) + self.cpu.compile_loop(loop.inputargs, loop.operations, looptoken) argvals, expected_result = self._prepare_args(args, floats, ints) deadframe = self.cpu.execute_token(looptoken, *argvals) 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 @@ -49,7 +49,7 @@ valueboxes, descr) looptoken = JitCellToken() - self.cpu.compile_loop(None, inputargs, operations, looptoken) + self.cpu.compile_loop(inputargs, operations, looptoken) args = [] for box in inputargs: if isinstance(box, BoxInt): @@ -127,7 +127,7 @@ ] inputargs = [i0] looptoken = JitCellToken() - self.cpu.compile_loop(None, inputargs, operations, looptoken) + self.cpu.compile_loop(inputargs, operations, looptoken) deadframe = self.cpu.execute_token(looptoken, 2) fail = self.cpu.get_latest_descr(deadframe) res = self.cpu.get_int_value(deadframe, 0) @@ -145,7 +145,7 @@ ] inputargs = [i0] looptoken = JitCellToken() - self.cpu.compile_loop(None, inputargs, operations, looptoken) + self.cpu.compile_loop(inputargs, operations, looptoken) deadframe = self.cpu.execute_token(looptoken, longlong.getfloatstorage(2.8)) fail = self.cpu.get_latest_descr(deadframe) @@ -170,7 +170,7 @@ inputargs = [i0] operations[3].setfailargs([i1]) - self.cpu.compile_loop(None, inputargs, operations, looptoken) + self.cpu.compile_loop(inputargs, operations, looptoken) deadframe = self.cpu.execute_token(looptoken, 2) fail = self.cpu.get_latest_descr(deadframe) assert fail.identifier == 2 @@ -195,7 +195,7 @@ inputargs = [i3] operations[4].setfailargs([None, None, i1, None]) - self.cpu.compile_loop(None, inputargs, operations, looptoken) + self.cpu.compile_loop(inputargs, operations, looptoken) deadframe = self.cpu.execute_token(looptoken, 44) fail = self.cpu.get_latest_descr(deadframe) assert fail.identifier == 2 @@ -221,7 +221,7 @@ operations[3].setfailargs([i1]) wr_i1 = weakref.ref(i1) wr_guard = weakref.ref(operations[2]) - self.cpu.compile_loop(None, inputargs, operations, looptoken) + self.cpu.compile_loop(inputargs, operations, looptoken) if hasattr(looptoken, '_x86_ops_offset'): del looptoken._x86_ops_offset # else it's kept alive del i0, i1, i2 @@ -249,7 +249,7 @@ ] inputargs = [i0] operations[3].setfailargs([i1]) - self.cpu.compile_loop(None, inputargs, operations, looptoken) + self.cpu.compile_loop(inputargs, operations, looptoken) i1b = BoxInt() i3 = BoxInt() @@ -260,7 +260,7 @@ ] bridge[1].setfailargs([i1b]) - self.cpu.compile_bridge(None, faildescr1, [i1b], bridge, looptoken) + self.cpu.compile_bridge(faildescr1, [i1b], bridge, looptoken) deadframe = self.cpu.execute_token(looptoken, 2) fail = self.cpu.get_latest_descr(deadframe) @@ -291,7 +291,7 @@ ] inputargs = [i3] operations[4].setfailargs([None, i1, None]) - self.cpu.compile_loop(None, inputargs, operations, looptoken) + self.cpu.compile_loop(inputargs, operations, looptoken) i1b = BoxInt() i3 = BoxInt() @@ -302,7 +302,7 @@ ] bridge[1].setfailargs([i1b]) - self.cpu.compile_bridge(None, faildescr1, [i1b], bridge, looptoken) + self.cpu.compile_bridge(faildescr1, [i1b], bridge, looptoken) deadframe = self.cpu.execute_token(looptoken, 2) fail = self.cpu.get_latest_descr(deadframe) @@ -320,7 +320,7 @@ ] inputargs = [i0] operations[0].setfailargs([i0]) - self.cpu.compile_loop(None, inputargs, operations, looptoken) + self.cpu.compile_loop(inputargs, operations, looptoken) i1list = [BoxInt() for i in range(150)] bridge = [] @@ -334,7 +334,7 @@ descr=BasicFinalDescr(4))) bridge[-2].setfailargs(i1list) - self.cpu.compile_bridge(None, faildescr1, [i0], bridge, looptoken) + self.cpu.compile_bridge(faildescr1, [i0], bridge, looptoken) deadframe = self.cpu.execute_token(looptoken, 1) fail = self.cpu.get_latest_descr(deadframe) @@ -358,7 +358,7 @@ operations = [ ResOperation(rop.FINISH, [i0], None, descr=faildescr) ] - self.cpu.compile_loop(None, [i0], operations, looptoken) + self.cpu.compile_loop([i0], operations, looptoken) deadframe = self.cpu.execute_token(looptoken, 99) fail = self.cpu.get_latest_descr(deadframe) assert fail is faildescr @@ -369,7 +369,7 @@ operations = [ ResOperation(rop.FINISH, [ConstInt(42)], None, descr=faildescr) ] - self.cpu.compile_loop(None, [], operations, looptoken) + self.cpu.compile_loop([], operations, looptoken) deadframe = self.cpu.execute_token(looptoken) fail = self.cpu.get_latest_descr(deadframe) assert fail is faildescr @@ -380,7 +380,7 @@ operations = [ ResOperation(rop.FINISH, [], None, descr=faildescr) ] - self.cpu.compile_loop(None, [], operations, looptoken) + self.cpu.compile_loop([], operations, looptoken) deadframe = self.cpu.execute_token(looptoken) fail = self.cpu.get_latest_descr(deadframe) assert fail is faildescr @@ -391,7 +391,7 @@ operations = [ ResOperation(rop.FINISH, [f0], None, descr=faildescr) ] - self.cpu.compile_loop(None, [f0], operations, looptoken) + self.cpu.compile_loop([f0], operations, looptoken) value = longlong.getfloatstorage(-61.25) deadframe = self.cpu.execute_token(looptoken, value) fail = self.cpu.get_latest_descr(deadframe) @@ -403,7 +403,7 @@ operations = [ ResOperation(rop.FINISH, [constfloat(42.5)], None, descr=faildescr) ] - self.cpu.compile_loop(None, [], operations, looptoken) + self.cpu.compile_loop([], operations, looptoken) deadframe = self.cpu.execute_token(looptoken) fail = self.cpu.get_latest_descr(deadframe) assert fail is faildescr @@ -429,7 +429,7 @@ ResOperation(rop.JUMP, [t, z], None, descr=targettoken), ] operations[-2].setfailargs([t, z]) - cpu.compile_loop(None, [x, y], operations, looptoken) + cpu.compile_loop([x, y], operations, looptoken) deadframe = self.cpu.execute_token(looptoken, 0, 10) assert self.cpu.get_int_value(deadframe, 0) == 0 assert self.cpu.get_int_value(deadframe, 1) == 55 @@ -488,7 +488,7 @@ ops[1].setfailargs([v_res]) # looptoken = JitCellToken() - self.cpu.compile_loop(None, [v1, v2], ops, looptoken) + self.cpu.compile_loop([v1, v2], ops, looptoken) for x, y, z in testcases: deadframe = self.cpu.execute_token(looptoken, x, y) fail = self.cpu.get_latest_descr(deadframe) @@ -1238,7 +1238,7 @@ print inputargs for op in operations: print op - self.cpu.compile_loop(None, inputargs, operations, looptoken) + self.cpu.compile_loop(inputargs, operations, looptoken) # deadframe = self.cpu.execute_token(looptoken, *values) fail = self.cpu.get_latest_descr(deadframe) @@ -1305,7 +1305,7 @@ operations[3].setfailargs(inputargs[:]) operations[3].setdescr(faildescr) # - self.cpu.compile_loop(None, inputargs, operations, looptoken) + self.cpu.compile_loop(inputargs, operations, looptoken) # values = [] S = lltype.GcStruct('S') @@ -1366,7 +1366,7 @@ operations[-3].setfailargs(fboxes) operations[-2].setfailargs(fboxes) looptoken = JitCellToken() - self.cpu.compile_loop(None, fboxes, operations, looptoken) + self.cpu.compile_loop(fboxes, operations, looptoken) fboxes2 = [BoxFloat() for i in range(12)] f3 = BoxFloat() @@ -1375,7 +1375,7 @@ ResOperation(rop.JUMP, [f3]+fboxes2[1:], None, descr=targettoken), ] - self.cpu.compile_bridge(None, faildescr1, fboxes2, bridge, looptoken) + self.cpu.compile_bridge(faildescr1, fboxes2, bridge, looptoken) args = [] for i in range(len(fboxes)): @@ -1407,7 +1407,7 @@ finish()""" loop = parse(loopops) looptoken = JitCellToken() - self.cpu.compile_loop(None, loop.inputargs, loop.operations, looptoken) + self.cpu.compile_loop(loop.inputargs, loop.operations, looptoken) args = [1] args.append(longlong.getfloatstorage(132.25)) args.append(longlong.getfloatstorage(0.75)) @@ -1428,7 +1428,7 @@ ResOperation(rop.FINISH, [], None, descr=faildescr2), ] bridgeops[-2].setfailargs(fboxes[:]) - self.cpu.compile_bridge(None, loop.operations[-2].getdescr(), fboxes, + self.cpu.compile_bridge(loop.operations[-2].getdescr(), fboxes, bridgeops, looptoken) args = [1, longlong.getfloatstorage(132.25), @@ -1463,7 +1463,7 @@ ] operations[1].setfailargs([]) looptoken = JitCellToken() - self.cpu.compile_loop(None, inputargs, operations, looptoken) + self.cpu.compile_loop(inputargs, operations, looptoken) # for value in [-42, 0, 1, 10]: deadframe = self.cpu.execute_token(looptoken, value) @@ -1508,7 +1508,7 @@ ] operations[-2].setfailargs([]) looptoken = JitCellToken() - self.cpu.compile_loop(None, inputargs, operations, looptoken) + self.cpu.compile_loop(inputargs, operations, looptoken) # for test1 in [-65, -42, -11, 0, 1, 10]: if test1 == -42 or combinaison[0] == 'b': @@ -1560,7 +1560,7 @@ ] operations[-2].setfailargs([]) looptoken = JitCellToken() - self.cpu.compile_loop(None, inputargs, operations, looptoken) + self.cpu.compile_loop(inputargs, operations, looptoken) # for test1 in [65, 42, 11, 0, 1]: if test1 == 42 or combinaison[0] == 'b': @@ -1616,7 +1616,7 @@ ] operations[-2].setfailargs([]) looptoken = JitCellToken() - self.cpu.compile_loop(None, inputargs, operations, looptoken) + self.cpu.compile_loop(inputargs, operations, looptoken) # nan = 1e200 * 1e200 nan /= nan @@ -1675,7 +1675,7 @@ descr=faildescr)) looptoken = JitCellToken() # - self.cpu.compile_loop(None, inputargs, operations, looptoken) + self.cpu.compile_loop(inputargs, operations, looptoken) # args = [] for box in inputargs: @@ -1748,7 +1748,7 @@ looptoken = JitCellToken() # Use "set" to unique-ify inputargs unique_testcase_list = list(set(testcase)) - self.cpu.compile_loop(None, unique_testcase_list, operations, + self.cpu.compile_loop(unique_testcase_list, operations, looptoken) args = [box.getfloatstorage() for box in unique_testcase_list] @@ -2065,7 +2065,7 @@ exc_ptr = xptr loop = parse(ops, self.cpu, namespace=locals()) looptoken = JitCellToken() - self.cpu.compile_loop(None, loop.inputargs, loop.operations, looptoken) + self.cpu.compile_loop(loop.inputargs, loop.operations, looptoken) deadframe = self.cpu.execute_token(looptoken, 1) assert self.cpu.get_ref_value(deadframe, 0) == xptr excvalue = self.cpu.grab_exc_value(deadframe) @@ -2088,7 +2088,7 @@ exc_ptr = yptr loop = parse(ops, self.cpu, namespace=locals()) looptoken = JitCellToken() - self.cpu.compile_loop(None, loop.inputargs, loop.operations, looptoken) + self.cpu.compile_loop(loop.inputargs, loop.operations, looptoken) deadframe = self.cpu.execute_token(looptoken, 1) assert self.cpu.get_int_value(deadframe, 0) == 1 excvalue = self.cpu.grab_exc_value(deadframe) @@ -2105,7 +2105,7 @@ ''' loop = parse(ops, self.cpu, namespace=locals()) looptoken = JitCellToken() - self.cpu.compile_loop(None, loop.inputargs, loop.operations, looptoken) + self.cpu.compile_loop(loop.inputargs, loop.operations, looptoken) deadframe = self.cpu.execute_token(looptoken, 1) assert self.cpu.get_int_value(deadframe, 0) == 1 excvalue = self.cpu.grab_exc_value(deadframe) @@ -2284,7 +2284,7 @@ 'func_ptr': func_ptr, 'calldescr': calldescr}) looptoken = JitCellToken() - self.cpu.compile_loop(None, loop.inputargs, loop.operations, looptoken) + self.cpu.compile_loop(loop.inputargs, loop.operations, looptoken) f1 = longlong.getfloatstorage(1.2) f2 = longlong.getfloatstorage(3.4) frame = self.cpu.execute_token(looptoken, 1, 0, 1, 2, 3, 4, 5, f1, f2) @@ -2329,7 +2329,7 @@ ] ops[2].setfailargs([i1, i0]) looptoken = JitCellToken() - self.cpu.compile_loop(None, [i0, i1], ops, looptoken) + self.cpu.compile_loop([i0, i1], ops, looptoken) deadframe = self.cpu.execute_token(looptoken, 20, 0) fail = self.cpu.get_latest_descr(deadframe) assert fail.identifier == 0 @@ -2375,7 +2375,7 @@ ] ops[2].setfailargs([i1, i2, i0]) looptoken = JitCellToken() - self.cpu.compile_loop(None, [i0, i1], ops, looptoken) + self.cpu.compile_loop([i0, i1], ops, looptoken) deadframe = self.cpu.execute_token(looptoken, 20, 0) fail = self.cpu.get_latest_descr(deadframe) assert fail.identifier == 0 @@ -2423,7 +2423,7 @@ ] ops[2].setfailargs([i1, f2, i0]) looptoken = JitCellToken() - self.cpu.compile_loop(None, [i0, i1], ops, looptoken) + self.cpu.compile_loop([i0, i1], ops, looptoken) deadframe = self.cpu.execute_token(looptoken, 20, 0) fail = self.cpu.get_latest_descr(deadframe) assert fail.identifier == 0 @@ -2465,7 +2465,7 @@ ] ops[1].setfailargs([i1, i2]) looptoken = JitCellToken() - self.cpu.compile_loop(None, [i1], ops, looptoken) + self.cpu.compile_loop([i1], ops, looptoken) deadframe = self.cpu.execute_token(looptoken, ord('G')) fail = self.cpu.get_latest_descr(deadframe) assert fail.identifier == 0 @@ -2523,7 +2523,7 @@ ] ops[1].setfailargs([]) looptoken = JitCellToken() - self.cpu.compile_loop(None, [i0, i1, i2, i3], ops, looptoken) + self.cpu.compile_loop([i0, i1, i2, i3], ops, looptoken) args = [rffi.cast(lltype.Signed, raw), 2, 4, @@ -2580,7 +2580,7 @@ ResOperation(rop.FINISH, [i3], None, descr=BasicFinalDescr(0)) ] looptoken = JitCellToken() - self.cpu.compile_loop(None, [i1, i2], ops, looptoken) + self.cpu.compile_loop([i1, i2], ops, looptoken) buffer = lltype.malloc(rffi.CCHARP.TO, buflen, flavor='raw') args = [buflen, rffi.cast(lltype.Signed, buffer)] @@ -2650,7 +2650,7 @@ ] ops[1].setfailargs([]) looptoken = JitCellToken() - self.cpu.compile_loop(None, [], ops, looptoken) + self.cpu.compile_loop([], ops, looptoken) deadframe = self.cpu.execute_token(looptoken) fail = self.cpu.get_latest_descr(deadframe) @@ -2790,7 +2790,7 @@ ops.insert(-1, ResOperation(rop.SAME_AS, [b1], b1.clonebox())) looptoken = JitCellToken() - self.cpu.compile_loop(None, argboxes, ops, looptoken) + self.cpu.compile_loop(argboxes, ops, looptoken) # seen = [] deadframe = self.cpu.execute_token(looptoken, *argvalues_normal) @@ -2815,7 +2815,7 @@ ] ops[0].setfailargs([i1]) looptoken = JitCellToken() - self.cpu.compile_loop(None, [i0, i1], ops, looptoken) + self.cpu.compile_loop([i0, i1], ops, looptoken) deadframe = self.cpu.execute_token(looptoken, -42, 9) fail = self.cpu.get_latest_descr(deadframe) @@ -2842,7 +2842,7 @@ ResOperation(rop.FINISH, [i2], None, descr=BasicFinalDescr(3)) ] ops[0].setfailargs([]) - self.cpu.compile_bridge(None, faildescr, [i2], ops, looptoken) + self.cpu.compile_bridge(faildescr, [i2], ops, looptoken) deadframe = self.cpu.execute_token(looptoken, -42, 9) fail = self.cpu.get_latest_descr(deadframe) @@ -2875,7 +2875,7 @@ ] ops[0].setfailargs([]) looptoken = JitCellToken() - self.cpu.compile_loop(None, [i0], ops, looptoken) + self.cpu.compile_loop([i0], ops, looptoken) # mark as failing self.cpu.invalidate_loop(looptoken) # attach a bridge @@ -2883,7 +2883,7 @@ ops2 = [ ResOperation(rop.JUMP, [ConstInt(333)], None, descr=labeldescr), ] - self.cpu.compile_bridge(None, faildescr, [], ops2, looptoken) + self.cpu.compile_bridge(faildescr, [], ops2, looptoken) # run: must not be caught in an infinite loop deadframe = self.cpu.execute_token(looptoken, 16) fail = self.cpu.get_latest_descr(deadframe) @@ -3091,7 +3091,7 @@ looptoken.outermost_jitdriver_sd = FakeJitDriverSD() finish_descr = loop.operations[-1].getdescr() self.cpu.done_with_this_frame_descr_int = BasicFinalDescr() - self.cpu.compile_loop(None, loop.inputargs, loop.operations, looptoken) + self.cpu.compile_loop(loop.inputargs, loop.operations, looptoken) ARGS = [lltype.Signed] * 10 RES = lltype.Signed FakeJitDriverSD.portal_calldescr = self.cpu.calldescrof( @@ -3109,7 +3109,7 @@ ''' loop = parse(ops, namespace=locals()) othertoken = JitCellToken() - self.cpu.compile_loop(None, loop.inputargs, loop.operations, othertoken) + self.cpu.compile_loop(loop.inputargs, loop.operations, othertoken) args = [i+1 for i in range(10)] deadframe = self.cpu.execute_token(othertoken, *args) assert self.cpu.get_int_value(deadframe, 0) == 13 @@ -3119,7 +3119,7 @@ del called[:] self.cpu.done_with_this_frame_descr_int = finish_descr othertoken = JitCellToken() - self.cpu.compile_loop(None, loop.inputargs, loop.operations, othertoken) + self.cpu.compile_loop(loop.inputargs, loop.operations, othertoken) args = [i+1 for i in range(10)] deadframe = self.cpu.execute_token(othertoken, *args) assert self.cpu.get_int_value(deadframe, 0) == 97 @@ -3157,7 +3157,7 @@ loop = parse(ops) looptoken = JitCellToken() looptoken.outermost_jitdriver_sd = FakeJitDriverSD() - self.cpu.compile_loop(None, loop.inputargs, loop.operations, looptoken) + self.cpu.compile_loop(loop.inputargs, loop.operations, looptoken) ARGS = [lltype.Signed] * 10 RES = lltype.Signed FakeJitDriverSD.portal_calldescr = self.cpu.calldescrof( @@ -3171,7 +3171,7 @@ ''' loop = parse(ops, namespace=locals()) othertoken = JitCellToken() - self.cpu.compile_loop(None, loop.inputargs, loop.operations, othertoken) + self.cpu.compile_loop(loop.inputargs, loop.operations, othertoken) deadframe = self.cpu.execute_token(othertoken, sys.maxint - 1) assert self.cpu.get_int_value(deadframe, 0) == 3 @@ -3209,7 +3209,7 @@ looptoken = JitCellToken() looptoken.outermost_jitdriver_sd = FakeJitDriverSD() self.cpu.done_with_this_frame_descr_float = BasicFinalDescr() - self.cpu.compile_loop(None, loop.inputargs, loop.operations, looptoken) + self.cpu.compile_loop(loop.inputargs, loop.operations, looptoken) args = [longlong.getfloatstorage(1.2), longlong.getfloatstorage(2.3)] deadframe = self.cpu.execute_token(looptoken, *args) @@ -3223,7 +3223,7 @@ ''' loop = parse(ops, namespace=locals()) othertoken = JitCellToken() - self.cpu.compile_loop(None, loop.inputargs, loop.operations, othertoken) + self.cpu.compile_loop(loop.inputargs, loop.operations, othertoken) args = [longlong.getfloatstorage(1.2), longlong.getfloatstorage(3.2)] deadframe = self.cpu.execute_token(othertoken, *args) @@ -3235,7 +3235,7 @@ del called[:] self.cpu.done_with_this_frame_descr_float = finish_descr othertoken = JitCellToken() - self.cpu.compile_loop(None, loop.inputargs, loop.operations, othertoken) + self.cpu.compile_loop(loop.inputargs, loop.operations, othertoken) args = [longlong.getfloatstorage(1.2), longlong.getfloatstorage(4.2)] deadframe = self.cpu.execute_token(othertoken, *args) @@ -3298,7 +3298,7 @@ looptoken = JitCellToken() looptoken.outermost_jitdriver_sd = FakeJitDriverSD() self.cpu.done_with_this_frame_descr_float = BasicFinalDescr() - self.cpu.compile_loop(None, loop.inputargs, loop.operations, looptoken) + self.cpu.compile_loop(loop.inputargs, loop.operations, looptoken) finish_descr = loop.operations[-1].getdescr() args = [longlong.getfloatstorage(1.25), longlong.getfloatstorage(2.35)] @@ -3315,7 +3315,7 @@ ''' loop = parse(ops, namespace=locals()) othertoken = JitCellToken() - self.cpu.compile_loop(None, loop.inputargs, loop.operations, othertoken) + self.cpu.compile_loop(loop.inputargs, loop.operations, othertoken) # normal call_assembler: goes to looptoken args = [longlong.getfloatstorage(1.25), @@ -3334,7 +3334,7 @@ loop2 = parse(ops) looptoken2 = JitCellToken() looptoken2.outermost_jitdriver_sd = FakeJitDriverSD() - self.cpu.compile_loop(None, loop2.inputargs, loop2.operations, looptoken2) + self.cpu.compile_loop(loop2.inputargs, loop2.operations, looptoken2) finish_descr2 = loop2.operations[-1].getdescr() # install it @@ -3694,7 +3694,7 @@ ] inputargs = [i0] looptoken = JitCellToken() - self.cpu.compile_loop(None, inputargs, operations, looptoken) + self.cpu.compile_loop(inputargs, operations, looptoken) # overflowing value: deadframe = self.cpu.execute_token(looptoken, sys.maxint // 4 + 1) fail = self.cpu.get_latest_descr(deadframe) @@ -3747,7 +3747,7 @@ operations[3].setfailargs([i1]) operations[6].setfailargs([i1]) - self.cpu.compile_loop(None, inputargs, operations, looptoken) + self.cpu.compile_loop(inputargs, operations, looptoken) deadframe = self.cpu.execute_token(looptoken, 2) fail = self.cpu.get_latest_descr(deadframe) assert fail.identifier == 2 @@ -3759,7 +3759,7 @@ ResOperation(rop.INT_SUB, [i0, ConstInt(20)], i2), ResOperation(rop.JUMP, [i2], None, descr=targettoken2), ] - self.cpu.compile_bridge(None, faildescr, inputargs2, operations2, looptoken) + self.cpu.compile_bridge(faildescr, inputargs2, operations2, looptoken) deadframe = self.cpu.execute_token(looptoken, 2) fail = self.cpu.get_latest_descr(deadframe) @@ -3776,7 +3776,7 @@ descr = BasicFinalDescr() loop = parse(ops, self.cpu, namespace=locals()) looptoken = JitCellToken() - self.cpu.compile_loop(None, loop.inputargs, loop.operations, looptoken) + self.cpu.compile_loop(loop.inputargs, loop.operations, looptoken) for inp, outp in [(2,2), (-3, 0)]: deadframe = self.cpu.execute_token(looptoken, inp) assert outp == self.cpu.get_int_value(deadframe, 0) @@ -3805,8 +3805,8 @@ bridge = parse(bridge_ops, self.cpu, namespace=locals()) looptoken = JitCellToken() self.cpu.assembler.set_debug(False) - info = self.cpu.compile_loop(None, loop.inputargs, loop.operations, looptoken) - bridge_info = self.cpu.compile_bridge(None, faildescr, bridge.inputargs, + info = self.cpu.compile_loop(loop.inputargs, loop.operations, looptoken) + bridge_info = self.cpu.compile_bridge(faildescr, bridge.inputargs, bridge.operations, looptoken) self.cpu.assembler.set_debug(True) # always on untranslated @@ -3850,7 +3850,7 @@ ResOperation(rop.FINISH, [i0], None, descr=BasicFinalDescr(1234)), ] operations[1].setfailargs([i0]) - self.cpu.compile_loop(None, inputargs, operations, looptoken1) + self.cpu.compile_loop(inputargs, operations, looptoken1) def func(a, b, c, d, e, f, g, h, i): assert a + 2 == b @@ -3904,14 +3904,14 @@ ResOperation(rop.JUMP, [i19], None, descr=targettoken1), ] operations2[-2].setfailargs([]) - self.cpu.compile_bridge(None, faildescr1, inputargs, operations2, looptoken1) + self.cpu.compile_bridge(faildescr1, inputargs, operations2, looptoken1) looptoken2 = JitCellToken() inputargs = [BoxInt()] operations3 = [ ResOperation(rop.JUMP, [ConstInt(0)], None, descr=targettoken1), ] - self.cpu.compile_loop(None, inputargs, operations3, looptoken2) + self.cpu.compile_loop(inputargs, operations3, looptoken2) deadframe = self.cpu.execute_token(looptoken2, -9) fail = self.cpu.get_latest_descr(deadframe) @@ -3928,11 +3928,11 @@ operations[0].setfailargs([]) looptoken = JitCellToken() inputargs = [t_box] - self.cpu.compile_loop(None, inputargs, operations, looptoken) + self.cpu.compile_loop(inputargs, operations, looptoken) operations = [ ResOperation(rop.FINISH, [], None, descr=BasicFinalDescr(99)) ] - self.cpu.compile_bridge(None, faildescr, [], operations, looptoken) + self.cpu.compile_bridge(faildescr, [], operations, looptoken) deadframe = self.cpu.execute_token(looptoken, null_box.getref_base()) fail = self.cpu.get_latest_descr(deadframe) assert fail.identifier == 99 @@ -3960,7 +3960,7 @@ # loop = parse(ops, self.cpu, namespace=locals()) looptoken = JitCellToken() - self.cpu.compile_loop(None, loop.inputargs, loop.operations, looptoken) + self.cpu.compile_loop(loop.inputargs, loop.operations, looptoken) deadframe = self.cpu.execute_token(looptoken, rffi.cast(lltype.Signed, p), 16) result = self.cpu.get_int_value(deadframe, 0) @@ -3990,7 +3990,7 @@ # loop = parse(ops, self.cpu, namespace=locals()) looptoken = JitCellToken() - self.cpu.compile_loop(None, loop.inputargs, loop.operations, looptoken) + self.cpu.compile_loop(loop.inputargs, loop.operations, looptoken) deadframe = self.cpu.execute_token(looptoken, rffi.cast(lltype.Signed, p), 16) result = self.cpu.get_float_value(deadframe, 0) @@ -4020,7 +4020,7 @@ # loop = parse(ops, self.cpu, namespace=locals()) looptoken = JitCellToken() - self.cpu.compile_loop(None, loop.inputargs, loop.operations, looptoken) + self.cpu.compile_loop(loop.inputargs, loop.operations, looptoken) deadframe = self.cpu.execute_token(looptoken, rffi.cast(lltype.Signed, p), 16) result = self.cpu.get_int_value(deadframe, 0) @@ -4052,7 +4052,7 @@ p[i] = '\xDD' loop = parse(ops, self.cpu, namespace=locals()) looptoken = JitCellToken() - self.cpu.compile_loop(None, loop.inputargs, loop.operations, looptoken) + self.cpu.compile_loop(loop.inputargs, loop.operations, looptoken) self.cpu.execute_token(looptoken, rffi.cast(lltype.Signed, p), 16, value) result = rawstorage.raw_storage_getitem(T, p, 16) @@ -4084,7 +4084,7 @@ p[i] = '\xDD' loop = parse(ops, self.cpu, namespace=locals()) looptoken = JitCellToken() - self.cpu.compile_loop(None, loop.inputargs, loop.operations, looptoken) + self.cpu.compile_loop(loop.inputargs, loop.operations, looptoken) self.cpu.execute_token(looptoken, rffi.cast(lltype.Signed, p), 16, longlong.getfloatstorage(value)) @@ -4118,7 +4118,7 @@ p[i] = '\xDD' loop = parse(ops, self.cpu, namespace=locals()) looptoken = JitCellToken() - self.cpu.compile_loop(None, loop.inputargs, loop.operations, looptoken) + self.cpu.compile_loop(loop.inputargs, loop.operations, looptoken) self.cpu.execute_token(looptoken, rffi.cast(lltype.Signed, p), 16, longlong.singlefloat2int(value)) @@ -4153,7 +4153,7 @@ ] ops[2].setfailargs([i2]) looptoken = JitCellToken() - self.cpu.compile_loop(None, [i0, i1], ops, looptoken) + self.cpu.compile_loop([i0, i1], ops, looptoken) deadframe = self.cpu.execute_token(looptoken, 20, 0) fail = self.cpu.get_latest_descr(deadframe) assert fail.identifier == 23 @@ -4187,7 +4187,7 @@ finish(i1, descr=finaldescr) """, namespace={'finaldescr': finaldescr, 'calldescr2': calldescr2, 'guarddescr': guarddescr, 'func2_ptr': func2_ptr}) - self.cpu.compile_bridge(None, faildescr, bridge.inputargs, + self.cpu.compile_bridge(faildescr, bridge.inputargs, bridge.operations, looptoken) cpu = self.cpu @@ -4220,7 +4220,7 @@ guard_true(i0, descr=faildescr) [i1, i2, px] finish(i2, descr=finaldescr2) """, namespace=locals()) - self.cpu.compile_loop(None, loop.inputargs, loop.operations, looptoken) + self.cpu.compile_loop(loop.inputargs, loop.operations, looptoken) frame = self.cpu.execute_token(looptoken, 0, 0, 3) assert self.cpu.get_latest_descr(frame) is guarddescr from rpython.jit.backend.llsupport.llmodel import AbstractLLCPU @@ -4269,7 +4269,7 @@ 'faildescr2': BasicFailDescr(1), 'xtp': xtp }) - self.cpu.compile_bridge(None, faildescr, bridge.inputargs, + self.cpu.compile_bridge(faildescr, bridge.inputargs, bridge.operations, looptoken) raise LLException(xtp, xptr) @@ -4290,7 +4290,7 @@ 'faildescr': faildescr, 'finaldescr2': BasicFinalDescr(1)}) - self.cpu.compile_loop(None, loop.inputargs, loop.operations, looptoken) + 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 diff --git a/rpython/jit/backend/test/test_random.py b/rpython/jit/backend/test/test_random.py --- a/rpython/jit/backend/test/test_random.py +++ b/rpython/jit/backend/test/test_random.py @@ -239,9 +239,9 @@ print >>s, ' operations[%d].setfailargs([%s])' % (i, fa) if fail_descr is None: print >>s, ' looptoken = JitCellToken()' - print >>s, ' cpu.compile_loop(None, inputargs, operations, looptoken)' + print >>s, ' cpu.compile_loop(inputargs, operations, looptoken)' else: - print >>s, ' cpu.compile_bridge(None, %s, inputargs, operations, looptoken)' % self.descr_counters[fail_descr] + print >>s, ' cpu.compile_bridge(%s, inputargs, operations, looptoken)' % self.descr_counters[fail_descr] if hasattr(self.loop, 'inputargs'): vals = [] for i, v in enumerate(self.loop.inputargs): @@ -643,7 +643,7 @@ self.builder = builder self.loop = loop dump(loop) - cpu.compile_loop(None, loop.inputargs, loop.operations, loop._jitcelltoken) + cpu.compile_loop(loop.inputargs, loop.operations, loop._jitcelltoken) if self.output: builder.print_loop(self.output) @@ -715,7 +715,7 @@ if box not in self.loop.inputargs: box = box.constbox() args.append(box) - self.cpu.compile_loop(None, self.loop.inputargs, + self.cpu.compile_loop(self.loop.inputargs, [ResOperation(rop.JUMP, args, None, descr=self.loop._targettoken)], self._initialjumploop_celltoken) @@ -851,7 +851,7 @@ if r.random() < .05: return False dump(subloop) - self.builder.cpu.compile_bridge(None, fail_descr, fail_args, + self.builder.cpu.compile_bridge(fail_descr, fail_args, subloop.operations, self.loop._jitcelltoken) 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 @@ -91,13 +91,13 @@ lines = machine_code_dump(data, addr, self.backend_name, label_list) print ''.join(lines) - def compile_loop(self, logger, inputargs, operations, looptoken, log=True, - name=''): + def compile_loop(self, inputargs, operations, looptoken, log=True, + name='', logger=None): return self.assembler.assemble_loop(logger, name, inputargs, operations, looptoken, log=log) - def compile_bridge(self, logger, faildescr, inputargs, operations, - original_loop_token, log=True): + def compile_bridge(self, faildescr, inputargs, operations, + original_loop_token, log=True, logger=None): clt = original_loop_token.compiled_loop_token clt.compiling_a_bridge() return self.assembler.assemble_bridge(logger, faildescr, inputargs, diff --git a/rpython/jit/backend/x86/test/test_regalloc2.py b/rpython/jit/backend/x86/test/test_regalloc2.py --- a/rpython/jit/backend/x86/test/test_regalloc2.py +++ b/rpython/jit/backend/x86/test/test_regalloc2.py @@ -32,7 +32,7 @@ cpu = CPU(None, None) cpu.setup_once() looptoken = JitCellToken() - cpu.compile_loop(None, inputargs, operations, looptoken) + cpu.compile_loop(inputargs, operations, looptoken) deadframe = cpu.execute_token(looptoken, 9) assert cpu.get_int_value(deadframe, 0) == (9 >> 3) assert cpu.get_int_value(deadframe, 1) == (~18) @@ -58,7 +58,7 @@ cpu = CPU(None, None) cpu.setup_once() looptoken = JitCellToken() - cpu.compile_loop(None, inputargs, operations, looptoken) + cpu.compile_loop(inputargs, operations, looptoken) deadframe = cpu.execute_token(looptoken, -10) assert cpu.get_int_value(deadframe, 0) == 0 assert cpu.get_int_value(deadframe, 1) == -1000 @@ -159,7 +159,7 @@ cpu = CPU(None, None) cpu.setup_once() looptoken = JitCellToken() - cpu.compile_loop(None, inputargs, operations, looptoken) + cpu.compile_loop(inputargs, operations, looptoken) deadframe = cpu.execute_token(looptoken, -13, 10, 10, 8, -8, -16, -18, 46, -12, 26) assert cpu.get_int_value(deadframe, 0) == 0 @@ -271,7 +271,7 @@ cpu = CPU(None, None) cpu.setup_once() looptoken = JitCellToken() - cpu.compile_loop(None, inputargs, operations, looptoken) + cpu.compile_loop(inputargs, operations, looptoken) deadframe = cpu.execute_token(looptoken, 17, -20, -6, 6, 1, 13, 13, 9, 49, 8) assert cpu.get_int_value(deadframe, 0) == 0 @@ -386,7 +386,7 @@ operations[4].setfailargs([v4, v8, v10, v2, v9, v7, v6, v1]) operations[8].setfailargs([v3, v9, v2, v6, v4]) looptoken = JitCellToken() - cpu.compile_loop(None, inputargs, operations, looptoken) + cpu.compile_loop(inputargs, operations, looptoken) loop_args = [1, -39, 46, 21, 16, 6, -4611686018427387905, 12, 14, 2] frame = cpu.execute_token(looptoken, *loop_args) assert cpu.get_int_value(frame, 0) == 46 @@ -493,7 +493,7 @@ operations[16].setfailargs([v5, v9]) operations[34].setfailargs([]) operations[37].setfailargs([v12, v19, v10, v7, v4, v8, v18, v15, v9]) - cpu.compile_bridge(None, faildescr1, inputargs, operations, looptoken) + cpu.compile_bridge(faildescr1, inputargs, operations, looptoken) frame = cpu.execute_token(looptoken, *loop_args) #assert cpu.get_int_value(frame, 0) == -9223372036854775766 assert cpu.get_int_value(frame, 1) == 0 @@ -583,7 +583,7 @@ operations[0].setfailargs([]) operations[8].setfailargs([tmp23, v5, v3, v11, v6]) operations[30].setfailargs([v6]) - cpu.compile_bridge(None, faildescr6, inputargs, operations, looptoken) + cpu.compile_bridge(faildescr6, inputargs, operations, looptoken) frame = cpu.execute_token(looptoken, *loop_args) #assert cpu.get_int_value(frame, 0) == -9223372036854775808 v1 = BoxInt() @@ -607,6 +607,6 @@ ResOperation(rop.FINISH, [], None, descr=finishdescr13), ] operations[4].setfailargs([v2]) - cpu.compile_bridge(None, faildescr10, inputargs, operations, looptoken) + cpu.compile_bridge(faildescr10, inputargs, operations, looptoken) frame = cpu.execute_token(looptoken, *loop_args) #assert cpu.get_int_value(frame, 0) == 10 diff --git a/rpython/jit/backend/x86/test/test_runner.py b/rpython/jit/backend/x86/test/test_runner.py --- a/rpython/jit/backend/x86/test/test_runner.py +++ b/rpython/jit/backend/x86/test/test_runner.py @@ -287,7 +287,7 @@ ] ops[-2].setfailargs([i1]) looptoken = JitCellToken() - self.cpu.compile_loop(None, [b], ops, looptoken) + self.cpu.compile_loop([b], ops, looptoken) deadframe = self.cpu.execute_token(looptoken, b.value) result = self.cpu.get_int_value(deadframe, 0) if guard == rop.GUARD_FALSE: @@ -333,7 +333,7 @@ ops[-2].setfailargs([i1]) inputargs = [i for i in (a, b) if isinstance(i, Box)] looptoken = JitCellToken() - self.cpu.compile_loop(None, inputargs, ops, looptoken) + self.cpu.compile_loop(inputargs, ops, looptoken) inputvalues = [box.value for box in inputargs] deadframe = self.cpu.execute_token(looptoken, *inputvalues) result = self.cpu.get_int_value(deadframe, 0) @@ -377,7 +377,7 @@ ] inputargs = [i0] operations[-2].setfailargs([i1]) - self.cpu.compile_loop(None, inputargs, operations, looptoken) + self.cpu.compile_loop(inputargs, operations, looptoken) name, loopaddress, loopsize = agent.functions[0] assert name == "Loop # 17: hello (loop counter 0)" assert loopaddress <= looptoken._ll_loop_code @@ -393,7 +393,7 @@ ] bridge[1].setfailargs([i1b]) - self.cpu.compile_bridge(None, faildescr1, [i1b], bridge, looptoken) + self.cpu.compile_bridge(faildescr1, [i1b], bridge, looptoken) name, address, size = agent.functions[1] assert name == "Bridge # 0: bye (loop counter 1)" # Would be exactly ==, but there are some guard failure recovery @@ -422,7 +422,7 @@ ] inputargs = [i0] debug._log = dlog = debug.DebugLog() - info = self.cpu.compile_loop(None, inputargs, operations, looptoken) + info = self.cpu.compile_loop(inputargs, operations, looptoken) ops_offset = info.ops_offset debug._log = None # @@ -508,7 +508,7 @@ ops[5].setfailargs([]) ops[7].setfailargs([]) looptoken = JitCellToken() - self.cpu.compile_loop(None, [i1, i2], ops, looptoken) + self.cpu.compile_loop([i1, i2], ops, looptoken) deadframe = self.cpu.execute_token(looptoken, 123450, 123408) fail = self.cpu.get_latest_descr(deadframe) @@ -549,7 +549,7 @@ try: self.cpu.assembler.set_debug(True) looptoken = JitCellToken() - self.cpu.compile_loop(None, ops.inputargs, ops.operations, looptoken) + self.cpu.compile_loop(ops.inputargs, ops.operations, looptoken) self.cpu.execute_token(looptoken, 0) # check debugging info struct = self.cpu.assembler.loop_run_counters[0] 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 @@ -302,17 +302,17 @@ log=True, name=''): metainterp_sd.logger_ops.log_loop(inputargs, operations, -2, 'compiling', name=name) - return metainterp_sd.cpu.compile_loop(metainterp_sd.logger_ops, - inputargs, operations, looptoken, - log=log, name=name) + return metainterp_sd.cpu.compile_loop(inputargs, operations, looptoken, + log=log, name=name, + logger=metainterp_sd.logger_ops) def do_compile_bridge(metainterp_sd, faildescr, inputargs, operations, original_loop_token, log=True): metainterp_sd.logger_ops.log_bridge(inputargs, operations, "compiling") assert isinstance(faildescr, AbstractFailDescr) - return metainterp_sd.cpu.compile_bridge(metainterp_sd.logger_ops, - faildescr, inputargs, operations, - original_loop_token, log=log) + return metainterp_sd.cpu.compile_bridge(faildescr, inputargs, operations, + original_loop_token, log=log, + logger=metainterp_sd.logger_ops) def send_loop_to_backend(greenkey, jitdriver_sd, metainterp_sd, loop, type): vinfo = jitdriver_sd.virtualizable_info @@ -934,7 +934,7 @@ ] operations[1].setfailargs([]) operations = get_deep_immutable_oplist(operations) - cpu.compile_loop(None, inputargs, operations, jitcell_token, log=False) + cpu.compile_loop(inputargs, operations, jitcell_token, log=False) if memory_manager is not None: # for tests memory_manager.keep_loop_alive(jitcell_token) return jitcell_token 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 @@ -17,7 +17,8 @@ ts = typesystem.llhelper def __init__(self): self.seen = [] - def compile_loop(self, logger, inputargs, operations, token, log=True, name=''): + def compile_loop(self, inputargs, operations, token, log=True, name='', + logger=None): self.seen.append((inputargs, operations, token)) class FakeLogger(object): From noreply at buildbot.pypy.org Sun Sep 15 17:35:00 2013 From: noreply at buildbot.pypy.org (arigo) Date: Sun, 15 Sep 2013 17:35:00 +0200 (CEST) Subject: [pypy-commit] pypy default: Comment Message-ID: <20130915153500.198E21C016D@cobra.cs.uni-duesseldorf.de> Author: Armin Rigo Branch: Changeset: r66956:38798dfaa5c3 Date: 2013-09-15 17:34 +0200 http://bitbucket.org/pypy/pypy/changeset/38798dfaa5c3/ Log: Comment 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 @@ -70,7 +70,7 @@ def pop(self, size, tp, hint=-1): if size == 2: - return self._pop_two(tp) + return self._pop_two(tp) # 'hint' ignored for floats on 32-bit assert size == 1 if not self.master_node: return None From noreply at buildbot.pypy.org Sun Sep 15 19:14:51 2013 From: noreply at buildbot.pypy.org (mattip) Date: Sun, 15 Sep 2013 19:14:51 +0200 (CEST) Subject: [pypy-commit] pypy default: skip resource test if not posix Message-ID: <20130915171451.263741C0162@cobra.cs.uni-duesseldorf.de> Author: mattip Branch: Changeset: r66957:622e34025e15 Date: 2013-09-15 18:52 +0300 http://bitbucket.org/pypy/pypy/changeset/622e34025e15/ Log: skip resource test if not posix diff --git a/pypy/module/test_lib_pypy/test_resource.py b/pypy/module/test_lib_pypy/test_resource.py --- a/pypy/module/test_lib_pypy/test_resource.py +++ b/pypy/module/test_lib_pypy/test_resource.py @@ -3,6 +3,9 @@ from lib_pypy.ctypes_config_cache import rebuild from pypy.module.test_lib_pypy.support import import_lib_pypy +import os +if os.name != 'posix': + skip('resource.h only available on unix') class AppTestResource: From noreply at buildbot.pypy.org Sun Sep 15 19:14:54 2013 From: noreply at buildbot.pypy.org (mattip) Date: Sun, 15 Sep 2013 19:14:54 +0200 (CEST) Subject: [pypy-commit] pypy safe-win-mmap: merge default into branch Message-ID: <20130915171454.F33481C0162@cobra.cs.uni-duesseldorf.de> Author: mattip Branch: safe-win-mmap Changeset: r66958:9fae0928dc2f Date: 2013-09-15 20:02 +0300 http://bitbucket.org/pypy/pypy/changeset/9fae0928dc2f/ Log: merge default into branch diff too long, truncating to 2000 out of 2774 lines diff --git a/pypy/module/__pypy__/interp_time.py b/pypy/module/__pypy__/interp_time.py --- a/pypy/module/__pypy__/interp_time.py +++ b/pypy/module/__pypy__/interp_time.py @@ -48,11 +48,11 @@ c_clock_gettime = rffi.llexternal("clock_gettime", [lltype.Signed, lltype.Ptr(TIMESPEC)], rffi.INT, - compilation_info=CConfig._compilation_info_, threadsafe=False + compilation_info=CConfig._compilation_info_, releasegil=False ) c_clock_getres = rffi.llexternal("clock_getres", [lltype.Signed, lltype.Ptr(TIMESPEC)], rffi.INT, - compilation_info=CConfig._compilation_info_, threadsafe=False + compilation_info=CConfig._compilation_info_, releasegil=False ) @unwrap_spec(clk_id="c_int") 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 @@ -28,7 +28,7 @@ 'CreateSemaphoreA', [rffi.VOIDP, rffi.LONG, rffi.LONG, rwin32.LPCSTR], rwin32.HANDLE) _CloseHandle = rwin32.winexternal('CloseHandle', [rwin32.HANDLE], - rwin32.BOOL, threadsafe=False) + rwin32.BOOL, releasegil=False) _ReleaseSemaphore = rwin32.winexternal( 'ReleaseSemaphore', [rwin32.HANDLE, rffi.LONG, rffi.LONGP], rwin32.BOOL) @@ -82,8 +82,8 @@ _sem_open = external('sem_open', [rffi.CCHARP, rffi.INT, rffi.INT, rffi.UINT], SEM_T) - # tread sem_close as not threadsafe for now to be able to use the __del__ - _sem_close = external('sem_close', [SEM_T], rffi.INT, threadsafe=False) + # sem_close is releasegil=False to be able to use it in the __del__ + _sem_close = external('sem_close', [SEM_T], rffi.INT, releasegil=False) _sem_unlink = external('sem_unlink', [rffi.CCHARP], rffi.INT) _sem_wait = external('sem_wait', [SEM_T], rffi.INT) _sem_trywait = external('sem_trywait', [SEM_T], rffi.INT) 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 @@ -144,12 +144,12 @@ BZ2_bzCompressInit = external('BZ2_bzCompressInit', [bz_stream, rffi.INT, rffi.INT, rffi.INT], rffi.INT) BZ2_bzCompressEnd = external('BZ2_bzCompressEnd', [bz_stream], rffi.INT, - threadsafe=False) + releasegil=False) BZ2_bzCompress = external('BZ2_bzCompress', [bz_stream, rffi.INT], rffi.INT) BZ2_bzDecompressInit = external('BZ2_bzDecompressInit', [bz_stream, rffi.INT, rffi.INT], rffi.INT) BZ2_bzDecompressEnd = external('BZ2_bzDecompressEnd', [bz_stream], rffi.INT, - threadsafe=False) + releasegil=False) BZ2_bzDecompress = external('BZ2_bzDecompress', [bz_stream], rffi.INT) def _catch_bz2_error(space, bzerror): diff --git a/pypy/module/cppyy/capi/builtin_capi.py b/pypy/module/cppyy/capi/builtin_capi.py --- a/pypy/module/cppyy/capi/builtin_capi.py +++ b/pypy/module/cppyy/capi/builtin_capi.py @@ -27,7 +27,7 @@ _c_num_scopes = rffi.llexternal( "cppyy_num_scopes", [C_SCOPE], rffi.INT, - threadsafe=ts_reflect, + releasegil=ts_reflect, compilation_info=backend.eci) def c_num_scopes(space, cppscope): return _c_num_scopes(cppscope.handle) @@ -41,28 +41,28 @@ _c_resolve_name = rffi.llexternal( "cppyy_resolve_name", [rffi.CCHARP], rffi.CCHARP, - threadsafe=ts_reflect, + releasegil=ts_reflect, compilation_info=backend.eci) def c_resolve_name(space, name): return charp2str_free(space, _c_resolve_name(name)) _c_get_scope_opaque = rffi.llexternal( "cppyy_get_scope", [rffi.CCHARP], C_SCOPE, - threadsafe=ts_reflect, + releasegil=ts_reflect, compilation_info=backend.eci) def c_get_scope_opaque(space, name): return _c_get_scope_opaque(name) _c_get_template = rffi.llexternal( "cppyy_get_template", [rffi.CCHARP], C_TYPE, - threadsafe=ts_reflect, + releasegil=ts_reflect, compilation_info=backend.eci) def c_get_template(space, name): return _c_get_template(name) _c_actual_class = rffi.llexternal( "cppyy_actual_class", [C_TYPE, C_OBJECT], C_TYPE, - threadsafe=ts_reflect, + releasegil=ts_reflect, compilation_info=backend.eci) def c_actual_class(space, cppclass, cppobj): return _c_actual_class(cppclass.handle, cppobj) @@ -71,21 +71,21 @@ _c_allocate = rffi.llexternal( "cppyy_allocate", [C_TYPE], C_OBJECT, - threadsafe=ts_memory, + releasegil=ts_memory, compilation_info=backend.eci) def c_allocate(space, cppclass): return _c_allocate(cppclass.handle) _c_deallocate = rffi.llexternal( "cppyy_deallocate", [C_TYPE, C_OBJECT], lltype.Void, - threadsafe=ts_memory, + releasegil=ts_memory, compilation_info=backend.eci) def c_deallocate(space, cppclass, cppobject): _c_deallocate(cppclass.handle, cppobject) _c_destruct = rffi.llexternal( "cppyy_destruct", [C_TYPE, C_OBJECT], lltype.Void, - threadsafe=ts_call, + releasegil=ts_call, compilation_info=backend.eci) def c_destruct(space, cppclass, cppobject): _c_destruct(cppclass.handle, cppobject) @@ -94,63 +94,63 @@ _c_call_v = rffi.llexternal( "cppyy_call_v", [C_METHOD, C_OBJECT, rffi.INT, rffi.VOIDP], lltype.Void, - threadsafe=ts_call, + releasegil=ts_call, compilation_info=backend.eci) def c_call_v(space, cppmethod, cppobject, nargs, args): _c_call_v(cppmethod, cppobject, nargs, args) _c_call_b = rffi.llexternal( "cppyy_call_b", [C_METHOD, C_OBJECT, rffi.INT, rffi.VOIDP], rffi.UCHAR, - threadsafe=ts_call, + releasegil=ts_call, compilation_info=backend.eci) def c_call_b(space, cppmethod, cppobject, nargs, args): return _c_call_b(cppmethod, cppobject, nargs, args) _c_call_c = rffi.llexternal( "cppyy_call_c", [C_METHOD, C_OBJECT, rffi.INT, rffi.VOIDP], rffi.CHAR, - threadsafe=ts_call, + releasegil=ts_call, compilation_info=backend.eci) def c_call_c(space, cppmethod, cppobject, nargs, args): return _c_call_c(cppmethod, cppobject, nargs, args) _c_call_h = rffi.llexternal( "cppyy_call_h", [C_METHOD, C_OBJECT, rffi.INT, rffi.VOIDP], rffi.SHORT, - threadsafe=ts_call, + releasegil=ts_call, compilation_info=backend.eci) def c_call_h(space, cppmethod, cppobject, nargs, args): return _c_call_h(cppmethod, cppobject, nargs, args) _c_call_i = rffi.llexternal( "cppyy_call_i", [C_METHOD, C_OBJECT, rffi.INT, rffi.VOIDP], rffi.INT, - threadsafe=ts_call, + releasegil=ts_call, compilation_info=backend.eci) def c_call_i(space, cppmethod, cppobject, nargs, args): return _c_call_i(cppmethod, cppobject, nargs, args) _c_call_l = rffi.llexternal( "cppyy_call_l", [C_METHOD, C_OBJECT, rffi.INT, rffi.VOIDP], rffi.LONG, - threadsafe=ts_call, + releasegil=ts_call, compilation_info=backend.eci) def c_call_l(space, cppmethod, cppobject, nargs, args): return _c_call_l(cppmethod, cppobject, nargs, args) _c_call_ll = rffi.llexternal( "cppyy_call_ll", [C_METHOD, C_OBJECT, rffi.INT, rffi.VOIDP], rffi.LONGLONG, - threadsafe=ts_call, + releasegil=ts_call, compilation_info=backend.eci) def c_call_ll(space, cppmethod, cppobject, nargs, args): return _c_call_ll(cppmethod, cppobject, nargs, args) _c_call_f = rffi.llexternal( "cppyy_call_f", [C_METHOD, C_OBJECT, rffi.INT, rffi.VOIDP], rffi.FLOAT, - threadsafe=ts_call, + releasegil=ts_call, compilation_info=backend.eci) def c_call_f(space, cppmethod, cppobject, nargs, args): return _c_call_f(cppmethod, cppobject, nargs, args) _c_call_d = rffi.llexternal( "cppyy_call_d", [C_METHOD, C_OBJECT, rffi.INT, rffi.VOIDP], rffi.DOUBLE, - threadsafe=ts_call, + releasegil=ts_call, compilation_info=backend.eci) def c_call_d(space, cppmethod, cppobject, nargs, args): return _c_call_d(cppmethod, cppobject, nargs, args) @@ -158,14 +158,14 @@ _c_call_r = rffi.llexternal( "cppyy_call_r", [C_METHOD, C_OBJECT, rffi.INT, rffi.VOIDP], rffi.VOIDP, - threadsafe=ts_call, + releasegil=ts_call, compilation_info=backend.eci) def c_call_r(space, cppmethod, cppobject, nargs, args): return _c_call_r(cppmethod, cppobject, nargs, args) _c_call_s = rffi.llexternal( "cppyy_call_s", [C_METHOD, C_OBJECT, rffi.INT, rffi.VOIDP], rffi.CCHARP, - threadsafe=ts_call, + releasegil=ts_call, compilation_info=backend.eci) def c_call_s(space, cppmethod, cppobject, nargs, args): return _c_call_s(cppmethod, cppobject, nargs, args) @@ -173,14 +173,14 @@ _c_constructor = rffi.llexternal( "cppyy_constructor", [C_METHOD, C_TYPE, rffi.INT, rffi.VOIDP], C_OBJECT, - threadsafe=ts_call, + releasegil=ts_call, compilation_info=backend.eci) def c_constructor(space, cppmethod, cppobject, nargs, args): return _c_constructor(cppmethod, cppobject, nargs, args) _c_call_o = rffi.llexternal( "cppyy_call_o", [C_METHOD, C_OBJECT, rffi.INT, rffi.VOIDP, C_TYPE], rffi.LONG, - threadsafe=ts_call, + releasegil=ts_call, compilation_info=backend.eci) def c_call_o(space, method, cppobj, nargs, args, cppclass): return _c_call_o(method, cppobj, nargs, args, cppclass.handle) @@ -188,7 +188,7 @@ _c_get_methptr_getter = rffi.llexternal( "cppyy_get_methptr_getter", [C_SCOPE, C_INDEX], C_METHPTRGETTER_PTR, - threadsafe=ts_reflect, + releasegil=ts_reflect, compilation_info=backend.eci, elidable_function=True) def c_get_methptr_getter(space, cppscope, index): @@ -198,21 +198,21 @@ _c_allocate_function_args = rffi.llexternal( "cppyy_allocate_function_args", [rffi.SIZE_T], rffi.VOIDP, - threadsafe=ts_memory, + releasegil=ts_memory, compilation_info=backend.eci) def c_allocate_function_args(space, size): return _c_allocate_function_args(size) _c_deallocate_function_args = rffi.llexternal( "cppyy_deallocate_function_args", [rffi.VOIDP], lltype.Void, - threadsafe=ts_memory, + releasegil=ts_memory, compilation_info=backend.eci) def c_deallocate_function_args(space, args): _c_deallocate_function_args(args) _c_function_arg_sizeof = rffi.llexternal( "cppyy_function_arg_sizeof", [], rffi.SIZE_T, - threadsafe=ts_memory, + releasegil=ts_memory, compilation_info=backend.eci, elidable_function=True) def c_function_arg_sizeof(space): @@ -220,7 +220,7 @@ _c_function_arg_typeoffset = rffi.llexternal( "cppyy_function_arg_typeoffset", [], rffi.SIZE_T, - threadsafe=ts_memory, + releasegil=ts_memory, compilation_info=backend.eci, elidable_function=True) def c_function_arg_typeoffset(space): @@ -230,14 +230,14 @@ _c_is_namespace = rffi.llexternal( "cppyy_is_namespace", [C_SCOPE], rffi.INT, - threadsafe=ts_reflect, + releasegil=ts_reflect, compilation_info=backend.eci) def c_is_namespace(space, scope): return _c_is_namespace(scope) _c_is_enum = rffi.llexternal( "cppyy_is_enum", [rffi.CCHARP], rffi.INT, - threadsafe=ts_reflect, + releasegil=ts_reflect, compilation_info=backend.eci) def c_is_enum(space, name): return _c_is_enum(name) @@ -246,42 +246,42 @@ _c_final_name = rffi.llexternal( "cppyy_final_name", [C_TYPE], rffi.CCHARP, - threadsafe=ts_reflect, + releasegil=ts_reflect, compilation_info=backend.eci) def c_final_name(space, cpptype): return charp2str_free(space, _c_final_name(cpptype)) _c_scoped_final_name = rffi.llexternal( "cppyy_scoped_final_name", [C_TYPE], rffi.CCHARP, - threadsafe=ts_reflect, + releasegil=ts_reflect, compilation_info=backend.eci) def c_scoped_final_name(space, cpptype): return charp2str_free(space, _c_scoped_final_name(cpptype)) _c_has_complex_hierarchy = rffi.llexternal( "cppyy_has_complex_hierarchy", [C_TYPE], rffi.INT, - threadsafe=ts_reflect, + releasegil=ts_reflect, compilation_info=backend.eci) def c_has_complex_hierarchy(space, cpptype): return _c_has_complex_hierarchy(cpptype) _c_num_bases = rffi.llexternal( "cppyy_num_bases", [C_TYPE], rffi.INT, - threadsafe=ts_reflect, + releasegil=ts_reflect, compilation_info=backend.eci) def c_num_bases(space, cppclass): return _c_num_bases(cppclass.handle) _c_base_name = rffi.llexternal( "cppyy_base_name", [C_TYPE, rffi.INT], rffi.CCHARP, - threadsafe=ts_reflect, + releasegil=ts_reflect, compilation_info=backend.eci) def c_base_name(space, cppclass, base_index): return charp2str_free(space, _c_base_name(cppclass.handle, base_index)) _c_is_subtype = rffi.llexternal( "cppyy_is_subtype", [C_TYPE, C_TYPE], rffi.INT, - threadsafe=ts_reflect, + releasegil=ts_reflect, compilation_info=backend.eci, elidable_function=True) @jit.elidable_promote('2') @@ -293,7 +293,7 @@ _c_base_offset = rffi.llexternal( "cppyy_base_offset", [C_TYPE, C_TYPE, C_OBJECT, rffi.INT], rffi.SIZE_T, - threadsafe=ts_reflect, + releasegil=ts_reflect, compilation_info=backend.eci, elidable_function=True) @jit.elidable_promote('1,2,4') @@ -308,21 +308,21 @@ _c_num_methods = rffi.llexternal( "cppyy_num_methods", [C_SCOPE], rffi.INT, - threadsafe=ts_reflect, + releasegil=ts_reflect, compilation_info=backend.eci) def c_num_methods(space, cppscope): return _c_num_methods(cppscope.handle) _c_method_index_at = rffi.llexternal( "cppyy_method_index_at", [C_SCOPE, rffi.INT], C_INDEX, - threadsafe=ts_reflect, + releasegil=ts_reflect, compilation_info=backend.eci) def c_method_index_at(space, cppscope, imethod): return _c_method_index_at(cppscope.handle, imethod) _c_method_indices_from_name = rffi.llexternal( "cppyy_method_indices_from_name", [C_SCOPE, rffi.CCHARP], C_INDEX_ARRAY, - threadsafe=ts_reflect, + releasegil=ts_reflect, compilation_info=backend.eci) def c_method_indices_from_name(space, cppscope, name): indices = _c_method_indices_from_name(cppscope.handle, name) @@ -341,49 +341,49 @@ _c_method_name = rffi.llexternal( "cppyy_method_name", [C_SCOPE, C_INDEX], rffi.CCHARP, - threadsafe=ts_reflect, + releasegil=ts_reflect, compilation_info=backend.eci) def c_method_name(space, cppscope, index): return charp2str_free(space, _c_method_name(cppscope.handle, index)) _c_method_result_type = rffi.llexternal( "cppyy_method_result_type", [C_SCOPE, C_INDEX], rffi.CCHARP, - threadsafe=ts_reflect, + releasegil=ts_reflect, compilation_info=backend.eci) def c_method_result_type(space, cppscope, index): return charp2str_free(space, _c_method_result_type(cppscope.handle, index)) _c_method_num_args = rffi.llexternal( "cppyy_method_num_args", [C_SCOPE, C_INDEX], rffi.INT, - threadsafe=ts_reflect, + releasegil=ts_reflect, compilation_info=backend.eci) def c_method_num_args(space, cppscope, index): return _c_method_num_args(cppscope.handle, index) _c_method_req_args = rffi.llexternal( "cppyy_method_req_args", [C_SCOPE, C_INDEX], rffi.INT, - threadsafe=ts_reflect, + releasegil=ts_reflect, compilation_info=backend.eci) def c_method_req_args(space, cppscope, index): return _c_method_req_args(cppscope.handle, index) _c_method_arg_type = rffi.llexternal( "cppyy_method_arg_type", [C_SCOPE, C_INDEX, rffi.INT], rffi.CCHARP, - threadsafe=ts_reflect, + releasegil=ts_reflect, compilation_info=backend.eci) def c_method_arg_type(space, cppscope, index, arg_index): return charp2str_free(space, _c_method_arg_type(cppscope.handle, index, arg_index)) _c_method_arg_default = rffi.llexternal( "cppyy_method_arg_default", [C_SCOPE, C_INDEX, rffi.INT], rffi.CCHARP, - threadsafe=ts_reflect, + releasegil=ts_reflect, compilation_info=backend.eci) def c_method_arg_default(space, cppscope, index, arg_index): return charp2str_free(space, _c_method_arg_default(cppscope.handle, index, arg_index)) _c_method_signature = rffi.llexternal( "cppyy_method_signature", [C_SCOPE, C_INDEX], rffi.CCHARP, - threadsafe=ts_reflect, + releasegil=ts_reflect, compilation_info=backend.eci) def c_method_signature(space, cppscope, index): return charp2str_free(space, _c_method_signature(cppscope.handle, index)) @@ -391,19 +391,19 @@ _c_method_is_template = rffi.llexternal( "cppyy_method_is_template", [C_SCOPE, C_INDEX], rffi.INT, - threadsafe=ts_reflect, + releasegil=ts_reflect, compilation_info=backend.eci) def c_method_is_template(space, 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, + releasegil=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, + releasegil=ts_reflect, compilation_info=backend.eci) def c_template_args(space, cppscope, index): nargs = _c_method_num_template_args(cppscope.handle, index) @@ -415,14 +415,14 @@ _c_get_method = rffi.llexternal( "cppyy_get_method", [C_SCOPE, C_INDEX], C_METHOD, - threadsafe=ts_reflect, + releasegil=ts_reflect, compilation_info=backend.eci) def c_get_method(space, cppscope, index): return _c_get_method(cppscope.handle, index) _c_get_global_operator = rffi.llexternal( "cppyy_get_global_operator", [C_SCOPE, C_SCOPE, C_SCOPE, rffi.CCHARP], WLAVC_INDEX, - threadsafe=ts_reflect, + releasegil=ts_reflect, compilation_info=backend.eci) def c_get_global_operator(space, nss, lc, rc, op): if nss is not None: @@ -433,14 +433,14 @@ _c_is_constructor = rffi.llexternal( "cppyy_is_constructor", [C_TYPE, C_INDEX], rffi.INT, - threadsafe=ts_reflect, + releasegil=ts_reflect, compilation_info=backend.eci) def c_is_constructor(space, cppclass, index): return _c_is_constructor(cppclass.handle, index) _c_is_staticmethod = rffi.llexternal( "cppyy_is_staticmethod", [C_TYPE, C_INDEX], rffi.INT, - threadsafe=ts_reflect, + releasegil=ts_reflect, compilation_info=backend.eci) def c_is_staticmethod(space, cppclass, index): return _c_is_staticmethod(cppclass.handle, index) @@ -449,28 +449,28 @@ _c_num_datamembers = rffi.llexternal( "cppyy_num_datamembers", [C_SCOPE], rffi.INT, - threadsafe=ts_reflect, + releasegil=ts_reflect, compilation_info=backend.eci) def c_num_datamembers(space, cppscope): return _c_num_datamembers(cppscope.handle) _c_datamember_name = rffi.llexternal( "cppyy_datamember_name", [C_SCOPE, rffi.INT], rffi.CCHARP, - threadsafe=ts_reflect, + releasegil=ts_reflect, compilation_info=backend.eci) def c_datamember_name(space, cppscope, datamember_index): return charp2str_free(space, _c_datamember_name(cppscope.handle, datamember_index)) _c_datamember_type = rffi.llexternal( "cppyy_datamember_type", [C_SCOPE, rffi.INT], rffi.CCHARP, - threadsafe=ts_reflect, + releasegil=ts_reflect, compilation_info=backend.eci) def c_datamember_type(space, cppscope, datamember_index): return charp2str_free(space, _c_datamember_type(cppscope.handle, datamember_index)) _c_datamember_offset = rffi.llexternal( "cppyy_datamember_offset", [C_SCOPE, rffi.INT], rffi.SIZE_T, - threadsafe=ts_reflect, + releasegil=ts_reflect, compilation_info=backend.eci) def c_datamember_offset(space, cppscope, datamember_index): return _c_datamember_offset(cppscope.handle, datamember_index) @@ -478,7 +478,7 @@ _c_datamember_index = rffi.llexternal( "cppyy_datamember_index", [C_SCOPE, rffi.CCHARP], rffi.INT, - threadsafe=ts_reflect, + releasegil=ts_reflect, compilation_info=backend.eci) def c_datamember_index(space, cppscope, name): return _c_datamember_index(cppscope.handle, name) @@ -487,14 +487,14 @@ _c_is_publicdata = rffi.llexternal( "cppyy_is_publicdata", [C_SCOPE, rffi.INT], rffi.INT, - threadsafe=ts_reflect, + releasegil=ts_reflect, compilation_info=backend.eci) def c_is_publicdata(space, cppscope, datamember_index): return _c_is_publicdata(cppscope.handle, datamember_index) _c_is_staticdata = rffi.llexternal( "cppyy_is_staticdata", [C_SCOPE, rffi.INT], rffi.INT, - threadsafe=ts_reflect, + releasegil=ts_reflect, compilation_info=backend.eci) def c_is_staticdata(space, cppscope, datamember_index): return _c_is_staticdata(cppscope.handle, datamember_index) @@ -503,21 +503,21 @@ _c_strtoll = rffi.llexternal( "cppyy_strtoll", [rffi.CCHARP], rffi.LONGLONG, - threadsafe=ts_helper, + releasegil=ts_helper, compilation_info=backend.eci) def c_strtoll(space, svalue): return _c_strtoll(svalue) _c_strtoull = rffi.llexternal( "cppyy_strtoull", [rffi.CCHARP], rffi.ULONGLONG, - threadsafe=ts_helper, + releasegil=ts_helper, compilation_info=backend.eci) def c_strtoull(space, svalue): return _c_strtoull(svalue) c_free = rffi.llexternal( "cppyy_free", [rffi.VOIDP], lltype.Void, - threadsafe=ts_memory, + releasegil=ts_memory, compilation_info=backend.eci) def charp2str_free(space, charp): @@ -529,7 +529,7 @@ _c_charp2stdstring = rffi.llexternal( "cppyy_charp2stdstring", [rffi.CCHARP], C_OBJECT, - threadsafe=ts_helper, + releasegil=ts_helper, compilation_info=backend.eci) def c_charp2stdstring(space, svalue): charp = rffi.str2charp(svalue) @@ -539,14 +539,14 @@ _c_stdstring2stdstring = rffi.llexternal( "cppyy_stdstring2stdstring", [C_OBJECT], C_OBJECT, - threadsafe=ts_helper, + releasegil=ts_helper, compilation_info=backend.eci) def c_stdstring2stdstring(space, cppobject): return _c_stdstring2stdstring(cppobject) _c_assign2stdstring = rffi.llexternal( "cppyy_assign2stdstring", [C_OBJECT, rffi.CCHARP], lltype.Void, - threadsafe=ts_helper, + releasegil=ts_helper, compilation_info=backend.eci) def c_assign2stdstring(space, cppobject, svalue): charp = rffi.str2charp(svalue) @@ -555,7 +555,7 @@ _c_free_stdstring = rffi.llexternal( "cppyy_free_stdstring", [C_OBJECT], lltype.Void, - threadsafe=ts_helper, + releasegil=ts_helper, compilation_info=backend.eci) def c_free_stdstring(space, cppobject): _c_free_stdstring(cppobject) 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 @@ -60,7 +60,7 @@ _c_load_dictionary = rffi.llexternal( "cppyy_load_dictionary", [rffi.CCHARP], rdynload.DLLHANDLE, - threadsafe=False, + releasegil=False, compilation_info=eci) def c_load_dictionary(name): @@ -84,7 +84,7 @@ _ttree_Branch = rffi.llexternal( "cppyy_ttree_Branch", [rffi.VOIDP, rffi.CCHARP, rffi.CCHARP, rffi.VOIDP, rffi.INT, rffi.INT], rffi.LONG, - threadsafe=False, + releasegil=False, compilation_info=eci) @unwrap_spec(args_w='args_w') @@ -158,7 +158,7 @@ c_ttree_GetEntry = rffi.llexternal( "cppyy_ttree_GetEntry", [rffi.VOIDP, rffi.LONGLONG], rffi.LONGLONG, - threadsafe=False, + releasegil=False, compilation_info=eci) @unwrap_spec(args_w='args_w') diff --git a/pypy/module/crypt/interp_crypt.py b/pypy/module/crypt/interp_crypt.py --- a/pypy/module/crypt/interp_crypt.py +++ b/pypy/module/crypt/interp_crypt.py @@ -8,7 +8,7 @@ else: eci = ExternalCompilationInfo(libraries=['crypt']) c_crypt = rffi.llexternal('crypt', [rffi.CCHARP, rffi.CCHARP], rffi.CCHARP, - compilation_info=eci, threadsafe=False) + compilation_info=eci, releasegil=False) @unwrap_spec(word=str, salt=str) def crypt(space, word, salt): 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 @@ -776,7 +776,13 @@ def test_unicode_boxes(self): from numpypy import unicode_ - assert isinstance(unicode_(3), unicode) + try: + u = unicode_(3) + except NotImplementedError, e: + if e.message.find('not supported yet') >= 0: + skip('unicode box not implemented') + else: + assert isinstance(u, unicode) def test_character_dtype(self): from numpypy import array, character 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 @@ -356,7 +356,7 @@ XML_ParserCreateNS = expat_external( 'XML_ParserCreateNS', [rffi.CCHARP, rffi.CHAR], XML_Parser) XML_ParserFree = expat_external( - 'XML_ParserFree', [XML_Parser], lltype.Void, threadsafe=False) + 'XML_ParserFree', [XML_Parser], lltype.Void, releasegil=False) XML_SetUserData = expat_external( 'XML_SetUserData', [XML_Parser, rffi.VOIDP], lltype.Void) def XML_GetUserData(parser): 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 @@ -151,7 +151,7 @@ return rffi.llexternal(name, args, result, compilation_info=eci, calling_conv=calling_conv, - threadsafe=False) + releasegil=False) if _POSIX: cConfig.timeval.__name__ = "_timeval" diff --git a/pypy/module/test_lib_pypy/test_resource.py b/pypy/module/test_lib_pypy/test_resource.py --- a/pypy/module/test_lib_pypy/test_resource.py +++ b/pypy/module/test_lib_pypy/test_resource.py @@ -3,6 +3,9 @@ from lib_pypy.ctypes_config_cache import rebuild from pypy.module.test_lib_pypy.support import import_lib_pypy +import os +if os.name != 'posix': + skip('resource.h only available on unix') class AppTestResource: 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 @@ -56,13 +56,13 @@ def finish_once(self): self.assembler.finish_once() - def compile_loop(self, logger, inputargs, operations, looptoken, - log=True, name=''): + def compile_loop(self, inputargs, operations, looptoken, + log=True, name='', logger=None): return self.assembler.assemble_loop(logger, name, inputargs, operations, looptoken, log=log) - def compile_bridge(self, logger, faildescr, inputargs, operations, - original_loop_token, log=True): + def compile_bridge(self, faildescr, inputargs, operations, + original_loop_token, log=True, logger=None): clt = original_loop_token.compiled_loop_token clt.compiling_a_bridge() return self.assembler.assemble_bridge(logger, faildescr, inputargs, 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 @@ -40,7 +40,7 @@ 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(None, inputargs, operations, looptoken) + cpu.compile_loop(inputargs, operations, looptoken) args = [-12 , -26 , -19 , 7 , -5 , -24 , -37 , 62 , 9 , 12] deadframe = cpu.execute_token(looptoken, *args) assert cpu.get_int_value(deadframe, 0) == 0 @@ -92,7 +92,7 @@ operations[9].setfailargs([v15, v7, v10, v18, v4, v17, v1]) operations[-1].setfailargs([v7, v1, v2]) looptoken = JitCellToken() - cpu.compile_loop(None, inputargs, operations, looptoken) + cpu.compile_loop(inputargs, operations, looptoken) args = [16 , 5 , 5 , 16 , 46 , 6 , 63 , 39 , 78 , 0] deadframe = cpu.execute_token(looptoken, *args) assert cpu.get_int_value(deadframe, 0) == 105 @@ -136,7 +136,7 @@ operations[-1].setfailargs([v5, v2, v1, v10, v3, v8, v4, v6]) looptoken = JitCellToken() - cpu.compile_loop(None, inputargs, operations, looptoken) + cpu.compile_loop(inputargs, operations, looptoken) args = [-5 , 24 , 46 , -15 , 13 , -8 , 0 , -6 , 6 , 6] deadframe = cpu.execute_token(looptoken, *args) assert cpu.get_latest_descr(deadframe).identifier == 2 @@ -179,7 +179,7 @@ operations[5].setfailargs([]) operations[-1].setfailargs([v8, v2, v6, v5, v7, v1, v10]) looptoken = JitCellToken() - cpu.compile_loop(None, inputargs, operations, looptoken) + cpu.compile_loop(inputargs, operations, looptoken) args = [19 , -3 , -58 , -7 , 12 , 22 , -54 , -29 , -19 , -64] deadframe = cpu.execute_token(looptoken, *args) assert cpu.get_int_value(deadframe, 0) == -29 @@ -223,7 +223,7 @@ looptoken = JitCellToken() operations[5].setfailargs([]) operations[-1].setfailargs([v1, v4, v10, v8, v7, v3]) - cpu.compile_loop(None, inputargs, operations, looptoken) + cpu.compile_loop(inputargs, operations, looptoken) args = [1073741824 , 95 , -16 , 5 , 92 , 12 , 32 , 17 , 37 , -63] deadframe = cpu.execute_token(looptoken, *args) assert cpu.get_int_value(deadframe, 0) == 1073741824 @@ -280,7 +280,7 @@ 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(None, inputargs, operations, looptoken) + cpu.compile_loop(inputargs, operations, looptoken) deadframe = cpu.execute_token(looptoken, *args) assert cpu.get_latest_descr(deadframe).identifier == 3 assert cpu.get_int_value(deadframe, 0) == 12 @@ -328,7 +328,7 @@ operations[8].setfailargs([v5, v9]) operations[-1].setfailargs([v4, v10, v6, v5, v9, v7]) looptoken = JitCellToken() - cpu.compile_loop(None, inputargs, operations, looptoken) + cpu.compile_loop(inputargs, operations, looptoken) args = [-8 , 0 , 62 , 35 , 16 , 9 , 30 , 581610154 , -1 , 738197503] deadframe = cpu.execute_token(looptoken, *args) assert cpu.get_latest_descr(deadframe).identifier == 2 @@ -378,7 +378,7 @@ operations[-2].setfailargs([v9, v4, v10, v11, v14]) operations[-1].setfailargs([v10, v8, v1, v6, v4]) looptoken = JitCellToken() - cpu.compile_loop(None, inputargs, operations, looptoken) + cpu.compile_loop(inputargs, operations, looptoken) args = [-39 , -18 , 1588243114 , -9 , -4 , 1252698794 , 0 , 715827882 , -15 , 536870912] deadframe = cpu.execute_token(looptoken, *args) assert cpu.get_latest_descr(deadframe).identifier == 1 @@ -433,7 +433,7 @@ operations[9].setfailargs([v5, v7, v12, v14, v2, v13, v8]) operations[-1].setfailargs([v1, v2, v9]) looptoken = JitCellToken() - cpu.compile_loop(None, inputargs, operations, looptoken) + cpu.compile_loop(inputargs, operations, looptoken) args = [0 , -2 , 24 , 1 , -4 , 13 , -95 , 33 , 2 , -44] deadframe = cpu.execute_token(looptoken, *args) assert cpu.get_latest_descr(deadframe).identifier == 3 @@ -475,7 +475,7 @@ 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(None, inputargs, operations, looptoken) + cpu.compile_loop(inputargs, operations, looptoken) args = [3 , -5 , 1431655765 , 47 , 12 , 1789569706 , 15 , 939524096 , 16 , -43] deadframe = cpu.execute_token(looptoken, *args) assert cpu.get_latest_descr(deadframe).identifier == 1 @@ -524,7 +524,7 @@ operations[-1].setfailargs([v2, v3, v5, v7, v10, v8, v9]) operations[4].setfailargs([v14]) looptoken = JitCellToken() - cpu.compile_loop(None, inputargs, operations, looptoken) + cpu.compile_loop(inputargs, operations, looptoken) args = [14 , -20 , 18 , -2058005163 , 6 , 1 , -16 , 11 , 0 , 19] deadframe = cpu.execute_token(looptoken, *args) assert cpu.get_latest_descr(deadframe).identifier == 1 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 @@ -24,7 +24,7 @@ cpu = CPU(None, None) cpu.setup_once() looptoken = JitCellToken() - cpu.compile_loop(None, inputargs, operations, looptoken) + cpu.compile_loop(inputargs, operations, looptoken) deadframe = cpu.execute_token(looptoken, 9) assert cpu.get_int_value(deadframe, 0) == (9 >> 3) assert cpu.get_int_value(deadframe, 1) == (~18) @@ -48,7 +48,7 @@ cpu = CPU(None, None) cpu.setup_once() looptoken = JitCellToken() - cpu.compile_loop(None, inputargs, operations, looptoken) + cpu.compile_loop(inputargs, operations, looptoken) deadframe = cpu.execute_token(looptoken, -10) assert cpu.get_int_value(deadframe, 0) == 0 assert cpu.get_int_value(deadframe, 1) == -1000 @@ -145,7 +145,7 @@ cpu = CPU(None, None) cpu.setup_once() looptoken = JitCellToken() - cpu.compile_loop(None, inputargs, operations, looptoken) + cpu.compile_loop(inputargs, operations, looptoken) args = [-13 , 10 , 10 , 8 , -8 , -16 , -18 , 46 , -12 , 26] deadframe = cpu.execute_token(looptoken, *args) assert cpu.get_int_value(deadframe, 0) == 0 @@ -252,7 +252,7 @@ cpu = CPU(None, None) cpu.setup_once() looptoken = JitCellToken() - cpu.compile_loop(None, inputargs, operations, looptoken) + cpu.compile_loop(inputargs, operations, looptoken) args = [17 , -20 , -6 , 6 , 1 , 13 , 13 , 9 , 49 , 8] deadframe = cpu.execute_token(looptoken, *args) assert cpu.get_int_value(deadframe, 0) == 0 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 @@ -75,7 +75,7 @@ ResOperation(rop.FINISH, [inp[1]], None, descr=BasicFinalDescr(1)), ] operations[-2].setfailargs(out) - cpu.compile_loop(None, inp, operations, looptoken) + cpu.compile_loop(inp, operations, looptoken) args = [i for i in range(1, 15)] deadframe = self.cpu.execute_token(looptoken, *args) output = [self.cpu.get_int_value(deadframe, i - 1) for i in range(1, 15)] @@ -117,9 +117,9 @@ i1 = int_sub(i0, 1) finish(i1) ''') - self.cpu.compile_loop(None, loop2.inputargs, loop2.operations, lt2) - self.cpu.compile_loop(None, loop3.inputargs, loop3.operations, lt3) - self.cpu.compile_loop(None, loop1.inputargs, loop1.operations, lt1) + self.cpu.compile_loop(loop2.inputargs, loop2.operations, lt2) + self.cpu.compile_loop(loop3.inputargs, loop3.operations, lt3) + self.cpu.compile_loop(loop1.inputargs, loop1.operations, lt1) df = self.cpu.execute_token(lt1, 10) assert self.cpu.get_int_value(df, 0) == 7 @@ -214,7 +214,7 @@ ops = "".join(ops) loop = parse(ops) looptoken = JitCellToken() - self.cpu.compile_loop(None, loop.inputargs, loop.operations, looptoken) + self.cpu.compile_loop(loop.inputargs, loop.operations, looptoken) ARGS = [lltype.Signed] * numargs RES = lltype.Signed args = [i+1 for i in range(numargs)] @@ -246,7 +246,7 @@ try: self.cpu.assembler.set_debug(True) looptoken = JitCellToken() - self.cpu.compile_loop(None, ops.inputargs, ops.operations, looptoken) + self.cpu.compile_loop(ops.inputargs, ops.operations, looptoken) self.cpu.execute_token(looptoken, 0) # check debugging info struct = self.cpu.assembler.loop_run_counters[0] @@ -280,7 +280,7 @@ faildescr = BasicFailDescr(2) loop = parse(ops, self.cpu, namespace=locals()) looptoken = JitCellToken() - info = self.cpu.compile_loop(None, loop.inputargs, loop.operations, looptoken) + info = self.cpu.compile_loop(loop.inputargs, loop.operations, looptoken) ops2 = """ [i0, f1] i1 = same_as(i0) @@ -293,7 +293,7 @@ """ loop2 = parse(ops2, self.cpu, namespace=locals()) looptoken2 = JitCellToken() - info = self.cpu.compile_loop(None, loop2.inputargs, loop2.operations, looptoken2) + info = self.cpu.compile_loop(loop2.inputargs, loop2.operations, looptoken2) deadframe = self.cpu.execute_token(looptoken, -9, longlong.getfloatstorage(-13.5)) res = longlong.getrealfloat(self.cpu.get_float_value(deadframe, 0)) 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 @@ -183,8 +183,8 @@ self.stats = stats or MiniStats() self.vinfo_for_tests = kwds.get('vinfo_for_tests', None) - def compile_loop(self, logger, inputargs, operations, looptoken, log=True, - name=''): + def compile_loop(self, inputargs, operations, looptoken, log=True, + name='', logger=None): clt = model.CompiledLoopToken(self, looptoken.number) looptoken.compiled_loop_token = clt lltrace = LLTrace(inputargs, operations) @@ -192,8 +192,8 @@ clt._llgraph_alltraces = [lltrace] self._record_labels(lltrace) - def compile_bridge(self, logger, faildescr, inputargs, operations, - original_loop_token, log=True): + def compile_bridge(self, faildescr, inputargs, operations, + original_loop_token, log=True, logger=None): clt = original_loop_token.compiled_loop_token clt.compiling_a_bridge() lltrace = LLTrace(inputargs, operations) 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 @@ -68,14 +68,32 @@ function(arg, node.val) node = node.next - def pop(self, size, tp): + def pop(self, size, tp, hint=-1): if size == 2: - return self._pop_two(tp) + return self._pop_two(tp) # 'hint' ignored for floats on 32-bit assert size == 1 if not self.master_node: return None node = self.master_node - self.master_node = node.next + # + if hint >= 0: + # Look for and remove the Node with the .val matching 'hint'. + # If not found, fall back to removing the first Node. + # Note that the loop below ignores the first Node, but + # even if by chance it is the one with the correct .val, + # it will be the one we remove at the end anyway. + prev_node = node + while prev_node.next: + if prev_node.next.val == hint: + node = prev_node.next + prev_node.next = node.next + break + prev_node = prev_node.next + else: + self.master_node = node.next + else: + self.master_node = node.next + # return self.fm.frame_pos(node.val, tp) def _candidate(self, node): @@ -131,8 +149,7 @@ def __init__(self, start_free_depth=0, freelist=None): self.bindings = {} self.current_frame_depth = start_free_depth - # we disable hints for now - #self.hint_frame_locations = {} + self.hint_frame_pos = {} self.freelist = LinkedList(self, freelist) def get_frame_depth(self): @@ -148,22 +165,16 @@ return self.bindings[box] except KeyError: pass - # check if we have a hint for this box - #if box in self.hint_frame_locations: - # # if we do, try to reuse the location for this box - # loc = self.hint_frame_locations[box] - # if self.try_to_reuse_location(box, loc): - # return loc - ## no valid hint. make up a new free location return self.get_new_loc(box) def get_new_loc(self, box): size = self.frame_size(box.type) + hint = self.hint_frame_pos.get(box, -1) # frame_depth is rounded up to a multiple of 'size', assuming # that 'size' is a power of two. The reason for doing so is to # avoid obscure issues in jump.py with stack locations that try # to move from position (6,7) to position (7,8). - newloc = self.freelist.pop(size, box.type) + newloc = self.freelist.pop(size, box.type, hint) if newloc is None: # index = self.get_frame_depth() @@ -232,23 +243,6 @@ all[node.val] = 1 node = node.next - def try_to_reuse_location(self, box, loc): - xxx - index = self.get_loc_index(loc) - if index < 0: - return False - size = self.frame_size(box.type) - for i in range(size): - while (index + i) >= len(self.used): - self.used.append(False) - if self.used[index + i]: - return False # already in use - # good, we can reuse the location - for i in range(size): - self.used[index + i] = True - self.bindings[box] = loc - return True - @staticmethod def _gather_gcroots(lst, var): lst.append(var) 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 @@ -676,7 +676,7 @@ 'checkdescr': checkdescr, 'fielddescr': cpu.fielddescrof(S, 'x')}) token = JitCellToken() - cpu.compile_loop(None, loop.inputargs, loop.operations, token) + cpu.compile_loop(loop.inputargs, loop.operations, token) p0 = lltype.malloc(S, zero=True) p1 = lltype.malloc(S) p2 = lltype.malloc(S) @@ -715,7 +715,7 @@ 'calldescr': checkdescr, }) token = JitCellToken() - cpu.compile_loop(None, loop.inputargs, loop.operations, token) + cpu.compile_loop(loop.inputargs, loop.operations, token) S = self.S s = lltype.malloc(S) cpu.execute_token(token, 1, s) @@ -743,7 +743,7 @@ token = JitCellToken() cpu.gc_ll_descr.init_nursery(20) cpu.setup_once() - cpu.compile_loop(None, loop.inputargs, loop.operations, token) + cpu.compile_loop(loop.inputargs, loop.operations, token) arg = longlong.getfloatstorage(2.3) frame = cpu.execute_token(token, arg) ofs = cpu.get_baseofs_of_frame_field() @@ -770,7 +770,7 @@ cpu.gc_ll_descr.collections = [[0, sizeof.size]] cpu.gc_ll_descr.init_nursery(2 * sizeof.size) cpu.setup_once() - cpu.compile_loop(None, loop.inputargs, loop.operations, token) + cpu.compile_loop(loop.inputargs, loop.operations, token) frame = cpu.execute_token(token) # now we should be able to track everything from the frame frame = lltype.cast_opaque_ptr(JITFRAMEPTR, frame) @@ -821,7 +821,7 @@ token = JitCellToken() cpu.gc_ll_descr.init_nursery(100) cpu.setup_once() - cpu.compile_loop(None, loop.inputargs, loop.operations, token) + cpu.compile_loop(loop.inputargs, loop.operations, token) args = [lltype.nullptr(llmemory.GCREF.TO) for i in range(7)] frame = cpu.execute_token(token, 1, *args) frame = rffi.cast(JITFRAMEPTR, frame) @@ -867,7 +867,7 @@ token = JitCellToken() cpu.gc_ll_descr.init_nursery(100) cpu.setup_once() - cpu.compile_loop(None, loop.inputargs, loop.operations, token) + cpu.compile_loop(loop.inputargs, loop.operations, token) frame = lltype.cast_opaque_ptr(JITFRAMEPTR, cpu.execute_token(token, 1, a)) @@ -911,7 +911,7 @@ token = JitCellToken() cpu.gc_ll_descr.init_nursery(100) cpu.setup_once() - cpu.compile_loop(None, loop.inputargs, loop.operations, token) + cpu.compile_loop(loop.inputargs, loop.operations, token) frame = lltype.cast_opaque_ptr(JITFRAMEPTR, cpu.execute_token(token, 1, a)) assert getmap(frame).count('1') == 4 diff --git a/rpython/jit/backend/llsupport/test/test_regalloc.py b/rpython/jit/backend/llsupport/test/test_regalloc.py --- a/rpython/jit/backend/llsupport/test/test_regalloc.py +++ b/rpython/jit/backend/llsupport/test/test_regalloc.py @@ -379,48 +379,23 @@ def test_hint_frame_locations_1(self): - py.test.skip("xxx") - b0, = newboxes(0) - fm = TFrameManager() - loc123 = FakeFramePos(123, INT) - fm.hint_frame_locations[b0] = loc123 - assert fm.get_frame_depth() == 0 - loc = fm.loc(b0) - assert loc == loc123 - assert fm.get_frame_depth() == 124 - - def test_hint_frame_locations_2(self): - py.test.skip("xxx") - b0, b1, b2 = newboxes(0, 1, 2) - longevity = {b0: (0, 1), b1: (0, 2), b2: (0, 2)} - fm = TFrameManager() - asm = MockAsm() - rm = RegisterManager(longevity, frame_manager=fm, assembler=asm) - rm.force_allocate_reg(b0) - rm.force_allocate_reg(b1) - rm.force_allocate_reg(b2) - rm.force_spill_var(b0) - loc = rm.loc(b0) - assert isinstance(loc, FakeFramePos) - assert fm.get_loc_index(loc) == 0 - rm.position = 1 - assert fm.used == [True] - rm.possibly_free_var(b0) - assert fm.used == [False] - # - fm.hint_frame_locations[b1] = loc - rm.force_spill_var(b1) - loc1 = rm.loc(b1) - assert loc1 == loc - assert fm.used == [True] - # - fm.hint_frame_locations[b2] = loc - rm.force_spill_var(b2) - loc2 = rm.loc(b2) - assert loc2 != loc1 # because it was not free - assert fm.used == [True, True] - # - rm._check_invariants() + for hint_value in range(11): + b0, = newboxes(0) + fm = TFrameManager() + fm.hint_frame_pos[b0] = hint_value + blist = newboxes(*range(10)) + for b1 in blist: + fm.loc(b1) + for b1 in blist: + fm.mark_as_free(b1) + assert fm.get_frame_depth() == 10 + loc = fm.loc(b0) + if hint_value < 10: + expected = hint_value + else: + expected = 0 + assert fm.get_loc_index(loc) == expected + assert fm.get_frame_depth() == 10 def test_linkedlist(self): class Loc(object): 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 @@ -97,7 +97,7 @@ loop = self.parse(ops, namespace=namespace) self.loop = loop looptoken = JitCellToken() - self.cpu.compile_loop(None, loop.inputargs, loop.operations, looptoken) + self.cpu.compile_loop(loop.inputargs, loop.operations, looptoken) arguments = [] for arg in args: if isinstance(arg, int): @@ -147,7 +147,7 @@ assert ([box.type for box in bridge.inputargs] == [box.type for box in guard_op.getfailargs()]) faildescr = guard_op.getdescr() - self.cpu.compile_bridge(None, faildescr, bridge.inputargs, + self.cpu.compile_bridge(faildescr, bridge.inputargs, bridge.operations, loop._jitcelltoken) return bridge diff --git a/rpython/jit/backend/llsupport/test/test_runner.py b/rpython/jit/backend/llsupport/test/test_runner.py --- a/rpython/jit/backend/llsupport/test/test_runner.py +++ b/rpython/jit/backend/llsupport/test/test_runner.py @@ -14,7 +14,7 @@ def set_debug(flag): pass - def compile_loop(self, logger, inputargs, operations, looptoken): + def compile_loop(self, inputargs, operations, looptoken): py.test.skip("llsupport test: cannot compile operations") 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 @@ -51,30 +51,21 @@ """ return False - def compile_loop(self, logger, inputargs, operations, looptoken, - log=True, name=''): + def compile_loop(self, inputargs, operations, looptoken, + log=True, name='', logger=None): """Assemble the given loop. Should create and attach a fresh CompiledLoopToken to looptoken.compiled_loop_token and stick extra attributes on it to point to the compiled loop in assembler. - - Optionally, return a ``ops_offset`` dictionary, which maps each operation - to its offset in the compiled code. The ``ops_offset`` dictionary is then - used by the operation logger to print the offsets in the log. The - offset representing the end of the last operation is stored in - ``ops_offset[None]``: note that this might not coincide with the end of - the loop, because usually in the loop footer there is code which does - not belong to any particular operation. + Returns either None or an instance of rpython.rlib.jit.AsmInfo. """ raise NotImplementedError - def compile_bridge(self, logger, faildescr, inputargs, operations, - original_loop_token, log=True): + def compile_bridge(self, faildescr, inputargs, operations, + original_loop_token, log=True, logger=None): """Assemble the bridge. The FailDescr is the descr of the original guard that failed. - - Optionally, return a ``ops_offset`` dictionary. See the docstring of - ``compiled_loop`` for more information about it. + Returns either None or an instance of rpython.rlib.jit.AsmInfo. """ raise NotImplementedError 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 @@ -105,7 +105,7 @@ loop = parse(ops, namespace=locals()) looptoken = JitCellToken() - self.cpu.compile_loop(None, loop.inputargs, loop.operations, looptoken) + self.cpu.compile_loop(loop.inputargs, loop.operations, looptoken) argvals, expected_result = self._prepare_args(args, floats, ints) deadframe = self.cpu.execute_token(looptoken, *argvals) @@ -249,7 +249,7 @@ called_looptoken = JitCellToken() called_looptoken.outermost_jitdriver_sd = FakeJitDriverSD() done_descr = called_loop.operations[-1].getdescr() - self.cpu.compile_loop(None, called_loop.inputargs, called_loop.operations, called_looptoken) + self.cpu.compile_loop(called_loop.inputargs, called_loop.operations, called_looptoken) argvals, expected_result = self._prepare_args(args, floats, ints) deadframe = cpu.execute_token(called_looptoken, *argvals) @@ -278,7 +278,7 @@ self.cpu.done_with_this_frame_descr_float = done_descr try: othertoken = JitCellToken() - self.cpu.compile_loop(None, loop.inputargs, loop.operations, othertoken) + self.cpu.compile_loop(loop.inputargs, loop.operations, othertoken) # prepare call to called_loop argvals, _ = self._prepare_args(args, floats, ints) @@ -424,7 +424,7 @@ loop = parse(ops, namespace=locals()) looptoken = JitCellToken() - self.cpu.compile_loop(None, loop.inputargs, loop.operations, looptoken) + self.cpu.compile_loop(loop.inputargs, loop.operations, looptoken) argvals, expected_result = self._prepare_args(args, floats, ints) deadframe = self.cpu.execute_token(looptoken, *argvals) 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 @@ -49,7 +49,7 @@ valueboxes, descr) looptoken = JitCellToken() - self.cpu.compile_loop(None, inputargs, operations, looptoken) + self.cpu.compile_loop(inputargs, operations, looptoken) args = [] for box in inputargs: if isinstance(box, BoxInt): @@ -127,7 +127,7 @@ ] inputargs = [i0] looptoken = JitCellToken() - self.cpu.compile_loop(None, inputargs, operations, looptoken) + self.cpu.compile_loop(inputargs, operations, looptoken) deadframe = self.cpu.execute_token(looptoken, 2) fail = self.cpu.get_latest_descr(deadframe) res = self.cpu.get_int_value(deadframe, 0) @@ -145,7 +145,7 @@ ] inputargs = [i0] looptoken = JitCellToken() - self.cpu.compile_loop(None, inputargs, operations, looptoken) + self.cpu.compile_loop(inputargs, operations, looptoken) deadframe = self.cpu.execute_token(looptoken, longlong.getfloatstorage(2.8)) fail = self.cpu.get_latest_descr(deadframe) @@ -170,7 +170,7 @@ inputargs = [i0] operations[3].setfailargs([i1]) - self.cpu.compile_loop(None, inputargs, operations, looptoken) + self.cpu.compile_loop(inputargs, operations, looptoken) deadframe = self.cpu.execute_token(looptoken, 2) fail = self.cpu.get_latest_descr(deadframe) assert fail.identifier == 2 @@ -195,7 +195,7 @@ inputargs = [i3] operations[4].setfailargs([None, None, i1, None]) - self.cpu.compile_loop(None, inputargs, operations, looptoken) + self.cpu.compile_loop(inputargs, operations, looptoken) deadframe = self.cpu.execute_token(looptoken, 44) fail = self.cpu.get_latest_descr(deadframe) assert fail.identifier == 2 @@ -221,7 +221,7 @@ operations[3].setfailargs([i1]) wr_i1 = weakref.ref(i1) wr_guard = weakref.ref(operations[2]) - self.cpu.compile_loop(None, inputargs, operations, looptoken) + self.cpu.compile_loop(inputargs, operations, looptoken) if hasattr(looptoken, '_x86_ops_offset'): del looptoken._x86_ops_offset # else it's kept alive del i0, i1, i2 @@ -249,7 +249,7 @@ ] inputargs = [i0] operations[3].setfailargs([i1]) - self.cpu.compile_loop(None, inputargs, operations, looptoken) + self.cpu.compile_loop(inputargs, operations, looptoken) i1b = BoxInt() i3 = BoxInt() @@ -260,7 +260,7 @@ ] bridge[1].setfailargs([i1b]) - self.cpu.compile_bridge(None, faildescr1, [i1b], bridge, looptoken) + self.cpu.compile_bridge(faildescr1, [i1b], bridge, looptoken) deadframe = self.cpu.execute_token(looptoken, 2) fail = self.cpu.get_latest_descr(deadframe) @@ -291,7 +291,7 @@ ] inputargs = [i3] operations[4].setfailargs([None, i1, None]) - self.cpu.compile_loop(None, inputargs, operations, looptoken) + self.cpu.compile_loop(inputargs, operations, looptoken) i1b = BoxInt() i3 = BoxInt() @@ -302,7 +302,7 @@ ] bridge[1].setfailargs([i1b]) - self.cpu.compile_bridge(None, faildescr1, [i1b], bridge, looptoken) + self.cpu.compile_bridge(faildescr1, [i1b], bridge, looptoken) deadframe = self.cpu.execute_token(looptoken, 2) fail = self.cpu.get_latest_descr(deadframe) @@ -320,7 +320,7 @@ ] inputargs = [i0] operations[0].setfailargs([i0]) - self.cpu.compile_loop(None, inputargs, operations, looptoken) + self.cpu.compile_loop(inputargs, operations, looptoken) i1list = [BoxInt() for i in range(150)] bridge = [] @@ -334,7 +334,7 @@ descr=BasicFinalDescr(4))) bridge[-2].setfailargs(i1list) - self.cpu.compile_bridge(None, faildescr1, [i0], bridge, looptoken) + self.cpu.compile_bridge(faildescr1, [i0], bridge, looptoken) deadframe = self.cpu.execute_token(looptoken, 1) fail = self.cpu.get_latest_descr(deadframe) @@ -358,7 +358,7 @@ operations = [ ResOperation(rop.FINISH, [i0], None, descr=faildescr) ] - self.cpu.compile_loop(None, [i0], operations, looptoken) + self.cpu.compile_loop([i0], operations, looptoken) deadframe = self.cpu.execute_token(looptoken, 99) fail = self.cpu.get_latest_descr(deadframe) assert fail is faildescr @@ -369,7 +369,7 @@ operations = [ ResOperation(rop.FINISH, [ConstInt(42)], None, descr=faildescr) ] - self.cpu.compile_loop(None, [], operations, looptoken) + self.cpu.compile_loop([], operations, looptoken) deadframe = self.cpu.execute_token(looptoken) fail = self.cpu.get_latest_descr(deadframe) assert fail is faildescr @@ -380,7 +380,7 @@ operations = [ ResOperation(rop.FINISH, [], None, descr=faildescr) ] - self.cpu.compile_loop(None, [], operations, looptoken) + self.cpu.compile_loop([], operations, looptoken) deadframe = self.cpu.execute_token(looptoken) fail = self.cpu.get_latest_descr(deadframe) assert fail is faildescr @@ -391,7 +391,7 @@ operations = [ ResOperation(rop.FINISH, [f0], None, descr=faildescr) ] - self.cpu.compile_loop(None, [f0], operations, looptoken) + self.cpu.compile_loop([f0], operations, looptoken) value = longlong.getfloatstorage(-61.25) deadframe = self.cpu.execute_token(looptoken, value) fail = self.cpu.get_latest_descr(deadframe) @@ -403,7 +403,7 @@ operations = [ ResOperation(rop.FINISH, [constfloat(42.5)], None, descr=faildescr) ] - self.cpu.compile_loop(None, [], operations, looptoken) + self.cpu.compile_loop([], operations, looptoken) deadframe = self.cpu.execute_token(looptoken) fail = self.cpu.get_latest_descr(deadframe) assert fail is faildescr @@ -429,7 +429,7 @@ ResOperation(rop.JUMP, [t, z], None, descr=targettoken), ] operations[-2].setfailargs([t, z]) - cpu.compile_loop(None, [x, y], operations, looptoken) + cpu.compile_loop([x, y], operations, looptoken) deadframe = self.cpu.execute_token(looptoken, 0, 10) assert self.cpu.get_int_value(deadframe, 0) == 0 assert self.cpu.get_int_value(deadframe, 1) == 55 @@ -488,7 +488,7 @@ ops[1].setfailargs([v_res]) # looptoken = JitCellToken() - self.cpu.compile_loop(None, [v1, v2], ops, looptoken) + self.cpu.compile_loop([v1, v2], ops, looptoken) for x, y, z in testcases: deadframe = self.cpu.execute_token(looptoken, x, y) fail = self.cpu.get_latest_descr(deadframe) @@ -1238,7 +1238,7 @@ print inputargs for op in operations: print op - self.cpu.compile_loop(None, inputargs, operations, looptoken) + self.cpu.compile_loop(inputargs, operations, looptoken) # deadframe = self.cpu.execute_token(looptoken, *values) fail = self.cpu.get_latest_descr(deadframe) @@ -1305,7 +1305,7 @@ operations[3].setfailargs(inputargs[:]) operations[3].setdescr(faildescr) # - self.cpu.compile_loop(None, inputargs, operations, looptoken) + self.cpu.compile_loop(inputargs, operations, looptoken) # values = [] S = lltype.GcStruct('S') @@ -1366,7 +1366,7 @@ operations[-3].setfailargs(fboxes) operations[-2].setfailargs(fboxes) looptoken = JitCellToken() - self.cpu.compile_loop(None, fboxes, operations, looptoken) + self.cpu.compile_loop(fboxes, operations, looptoken) fboxes2 = [BoxFloat() for i in range(12)] f3 = BoxFloat() @@ -1375,7 +1375,7 @@ ResOperation(rop.JUMP, [f3]+fboxes2[1:], None, descr=targettoken), ] - self.cpu.compile_bridge(None, faildescr1, fboxes2, bridge, looptoken) + self.cpu.compile_bridge(faildescr1, fboxes2, bridge, looptoken) args = [] for i in range(len(fboxes)): @@ -1407,7 +1407,7 @@ finish()""" loop = parse(loopops) looptoken = JitCellToken() - self.cpu.compile_loop(None, loop.inputargs, loop.operations, looptoken) + self.cpu.compile_loop(loop.inputargs, loop.operations, looptoken) args = [1] args.append(longlong.getfloatstorage(132.25)) args.append(longlong.getfloatstorage(0.75)) @@ -1428,7 +1428,7 @@ ResOperation(rop.FINISH, [], None, descr=faildescr2), ] bridgeops[-2].setfailargs(fboxes[:]) - self.cpu.compile_bridge(None, loop.operations[-2].getdescr(), fboxes, + self.cpu.compile_bridge(loop.operations[-2].getdescr(), fboxes, bridgeops, looptoken) args = [1, longlong.getfloatstorage(132.25), @@ -1463,7 +1463,7 @@ ] operations[1].setfailargs([]) looptoken = JitCellToken() - self.cpu.compile_loop(None, inputargs, operations, looptoken) + self.cpu.compile_loop(inputargs, operations, looptoken) # for value in [-42, 0, 1, 10]: deadframe = self.cpu.execute_token(looptoken, value) @@ -1508,7 +1508,7 @@ ] operations[-2].setfailargs([]) looptoken = JitCellToken() - self.cpu.compile_loop(None, inputargs, operations, looptoken) + self.cpu.compile_loop(inputargs, operations, looptoken) # for test1 in [-65, -42, -11, 0, 1, 10]: if test1 == -42 or combinaison[0] == 'b': @@ -1560,7 +1560,7 @@ ] operations[-2].setfailargs([]) looptoken = JitCellToken() - self.cpu.compile_loop(None, inputargs, operations, looptoken) + self.cpu.compile_loop(inputargs, operations, looptoken) # for test1 in [65, 42, 11, 0, 1]: if test1 == 42 or combinaison[0] == 'b': @@ -1616,7 +1616,7 @@ ] operations[-2].setfailargs([]) looptoken = JitCellToken() - self.cpu.compile_loop(None, inputargs, operations, looptoken) + self.cpu.compile_loop(inputargs, operations, looptoken) # nan = 1e200 * 1e200 nan /= nan @@ -1675,7 +1675,7 @@ descr=faildescr)) looptoken = JitCellToken() # - self.cpu.compile_loop(None, inputargs, operations, looptoken) + self.cpu.compile_loop(inputargs, operations, looptoken) # args = [] for box in inputargs: @@ -1748,7 +1748,7 @@ looptoken = JitCellToken() # Use "set" to unique-ify inputargs unique_testcase_list = list(set(testcase)) - self.cpu.compile_loop(None, unique_testcase_list, operations, + self.cpu.compile_loop(unique_testcase_list, operations, looptoken) args = [box.getfloatstorage() for box in unique_testcase_list] @@ -2065,7 +2065,7 @@ exc_ptr = xptr loop = parse(ops, self.cpu, namespace=locals()) looptoken = JitCellToken() - self.cpu.compile_loop(None, loop.inputargs, loop.operations, looptoken) + self.cpu.compile_loop(loop.inputargs, loop.operations, looptoken) deadframe = self.cpu.execute_token(looptoken, 1) assert self.cpu.get_ref_value(deadframe, 0) == xptr excvalue = self.cpu.grab_exc_value(deadframe) @@ -2088,7 +2088,7 @@ exc_ptr = yptr loop = parse(ops, self.cpu, namespace=locals()) looptoken = JitCellToken() - self.cpu.compile_loop(None, loop.inputargs, loop.operations, looptoken) + self.cpu.compile_loop(loop.inputargs, loop.operations, looptoken) deadframe = self.cpu.execute_token(looptoken, 1) assert self.cpu.get_int_value(deadframe, 0) == 1 excvalue = self.cpu.grab_exc_value(deadframe) @@ -2105,7 +2105,7 @@ ''' loop = parse(ops, self.cpu, namespace=locals()) looptoken = JitCellToken() - self.cpu.compile_loop(None, loop.inputargs, loop.operations, looptoken) + self.cpu.compile_loop(loop.inputargs, loop.operations, looptoken) deadframe = self.cpu.execute_token(looptoken, 1) assert self.cpu.get_int_value(deadframe, 0) == 1 excvalue = self.cpu.grab_exc_value(deadframe) @@ -2284,7 +2284,7 @@ 'func_ptr': func_ptr, 'calldescr': calldescr}) looptoken = JitCellToken() - self.cpu.compile_loop(None, loop.inputargs, loop.operations, looptoken) + self.cpu.compile_loop(loop.inputargs, loop.operations, looptoken) f1 = longlong.getfloatstorage(1.2) f2 = longlong.getfloatstorage(3.4) frame = self.cpu.execute_token(looptoken, 1, 0, 1, 2, 3, 4, 5, f1, f2) @@ -2329,7 +2329,7 @@ ] ops[2].setfailargs([i1, i0]) looptoken = JitCellToken() - self.cpu.compile_loop(None, [i0, i1], ops, looptoken) + self.cpu.compile_loop([i0, i1], ops, looptoken) deadframe = self.cpu.execute_token(looptoken, 20, 0) fail = self.cpu.get_latest_descr(deadframe) assert fail.identifier == 0 @@ -2375,7 +2375,7 @@ ] ops[2].setfailargs([i1, i2, i0]) looptoken = JitCellToken() - self.cpu.compile_loop(None, [i0, i1], ops, looptoken) + self.cpu.compile_loop([i0, i1], ops, looptoken) deadframe = self.cpu.execute_token(looptoken, 20, 0) fail = self.cpu.get_latest_descr(deadframe) assert fail.identifier == 0 @@ -2423,7 +2423,7 @@ ] ops[2].setfailargs([i1, f2, i0]) looptoken = JitCellToken() - self.cpu.compile_loop(None, [i0, i1], ops, looptoken) + self.cpu.compile_loop([i0, i1], ops, looptoken) deadframe = self.cpu.execute_token(looptoken, 20, 0) fail = self.cpu.get_latest_descr(deadframe) assert fail.identifier == 0 @@ -2465,7 +2465,7 @@ ] ops[1].setfailargs([i1, i2]) looptoken = JitCellToken() - self.cpu.compile_loop(None, [i1], ops, looptoken) + self.cpu.compile_loop([i1], ops, looptoken) deadframe = self.cpu.execute_token(looptoken, ord('G')) fail = self.cpu.get_latest_descr(deadframe) assert fail.identifier == 0 @@ -2523,7 +2523,7 @@ ] ops[1].setfailargs([]) looptoken = JitCellToken() - self.cpu.compile_loop(None, [i0, i1, i2, i3], ops, looptoken) + self.cpu.compile_loop([i0, i1, i2, i3], ops, looptoken) args = [rffi.cast(lltype.Signed, raw), 2, 4, @@ -2580,7 +2580,7 @@ ResOperation(rop.FINISH, [i3], None, descr=BasicFinalDescr(0)) ] looptoken = JitCellToken() - self.cpu.compile_loop(None, [i1, i2], ops, looptoken) + self.cpu.compile_loop([i1, i2], ops, looptoken) buffer = lltype.malloc(rffi.CCHARP.TO, buflen, flavor='raw') args = [buflen, rffi.cast(lltype.Signed, buffer)] @@ -2650,7 +2650,7 @@ ] ops[1].setfailargs([]) looptoken = JitCellToken() - self.cpu.compile_loop(None, [], ops, looptoken) + self.cpu.compile_loop([], ops, looptoken) deadframe = self.cpu.execute_token(looptoken) fail = self.cpu.get_latest_descr(deadframe) @@ -2790,7 +2790,7 @@ ops.insert(-1, ResOperation(rop.SAME_AS, [b1], b1.clonebox())) looptoken = JitCellToken() - self.cpu.compile_loop(None, argboxes, ops, looptoken) + self.cpu.compile_loop(argboxes, ops, looptoken) # seen = [] deadframe = self.cpu.execute_token(looptoken, *argvalues_normal) @@ -2815,7 +2815,7 @@ ] ops[0].setfailargs([i1]) looptoken = JitCellToken() - self.cpu.compile_loop(None, [i0, i1], ops, looptoken) + self.cpu.compile_loop([i0, i1], ops, looptoken) deadframe = self.cpu.execute_token(looptoken, -42, 9) fail = self.cpu.get_latest_descr(deadframe) @@ -2842,7 +2842,7 @@ ResOperation(rop.FINISH, [i2], None, descr=BasicFinalDescr(3)) ] ops[0].setfailargs([]) - self.cpu.compile_bridge(None, faildescr, [i2], ops, looptoken) + self.cpu.compile_bridge(faildescr, [i2], ops, looptoken) deadframe = self.cpu.execute_token(looptoken, -42, 9) fail = self.cpu.get_latest_descr(deadframe) @@ -2875,7 +2875,7 @@ ] ops[0].setfailargs([]) looptoken = JitCellToken() - self.cpu.compile_loop(None, [i0], ops, looptoken) + self.cpu.compile_loop([i0], ops, looptoken) # mark as failing self.cpu.invalidate_loop(looptoken) # attach a bridge @@ -2883,7 +2883,7 @@ ops2 = [ ResOperation(rop.JUMP, [ConstInt(333)], None, descr=labeldescr), ] - self.cpu.compile_bridge(None, faildescr, [], ops2, looptoken) + self.cpu.compile_bridge(faildescr, [], ops2, looptoken) # run: must not be caught in an infinite loop deadframe = self.cpu.execute_token(looptoken, 16) fail = self.cpu.get_latest_descr(deadframe) @@ -3091,7 +3091,7 @@ looptoken.outermost_jitdriver_sd = FakeJitDriverSD() finish_descr = loop.operations[-1].getdescr() self.cpu.done_with_this_frame_descr_int = BasicFinalDescr() - self.cpu.compile_loop(None, loop.inputargs, loop.operations, looptoken) + self.cpu.compile_loop(loop.inputargs, loop.operations, looptoken) ARGS = [lltype.Signed] * 10 RES = lltype.Signed FakeJitDriverSD.portal_calldescr = self.cpu.calldescrof( @@ -3109,7 +3109,7 @@ ''' loop = parse(ops, namespace=locals()) othertoken = JitCellToken() - self.cpu.compile_loop(None, loop.inputargs, loop.operations, othertoken) + self.cpu.compile_loop(loop.inputargs, loop.operations, othertoken) args = [i+1 for i in range(10)] deadframe = self.cpu.execute_token(othertoken, *args) assert self.cpu.get_int_value(deadframe, 0) == 13 @@ -3119,7 +3119,7 @@ del called[:] self.cpu.done_with_this_frame_descr_int = finish_descr othertoken = JitCellToken() - self.cpu.compile_loop(None, loop.inputargs, loop.operations, othertoken) + self.cpu.compile_loop(loop.inputargs, loop.operations, othertoken) args = [i+1 for i in range(10)] deadframe = self.cpu.execute_token(othertoken, *args) assert self.cpu.get_int_value(deadframe, 0) == 97 @@ -3157,7 +3157,7 @@ loop = parse(ops) looptoken = JitCellToken() looptoken.outermost_jitdriver_sd = FakeJitDriverSD() - self.cpu.compile_loop(None, loop.inputargs, loop.operations, looptoken) + self.cpu.compile_loop(loop.inputargs, loop.operations, looptoken) ARGS = [lltype.Signed] * 10 RES = lltype.Signed FakeJitDriverSD.portal_calldescr = self.cpu.calldescrof( @@ -3171,7 +3171,7 @@ ''' loop = parse(ops, namespace=locals()) othertoken = JitCellToken() - self.cpu.compile_loop(None, loop.inputargs, loop.operations, othertoken) + self.cpu.compile_loop(loop.inputargs, loop.operations, othertoken) deadframe = self.cpu.execute_token(othertoken, sys.maxint - 1) assert self.cpu.get_int_value(deadframe, 0) == 3 @@ -3209,7 +3209,7 @@ looptoken = JitCellToken() looptoken.outermost_jitdriver_sd = FakeJitDriverSD() self.cpu.done_with_this_frame_descr_float = BasicFinalDescr() - self.cpu.compile_loop(None, loop.inputargs, loop.operations, looptoken) + self.cpu.compile_loop(loop.inputargs, loop.operations, looptoken) args = [longlong.getfloatstorage(1.2), longlong.getfloatstorage(2.3)] deadframe = self.cpu.execute_token(looptoken, *args) @@ -3223,7 +3223,7 @@ ''' loop = parse(ops, namespace=locals()) othertoken = JitCellToken() - self.cpu.compile_loop(None, loop.inputargs, loop.operations, othertoken) + self.cpu.compile_loop(loop.inputargs, loop.operations, othertoken) args = [longlong.getfloatstorage(1.2), longlong.getfloatstorage(3.2)] deadframe = self.cpu.execute_token(othertoken, *args) @@ -3235,7 +3235,7 @@ del called[:] self.cpu.done_with_this_frame_descr_float = finish_descr othertoken = JitCellToken() - self.cpu.compile_loop(None, loop.inputargs, loop.operations, othertoken) + self.cpu.compile_loop(loop.inputargs, loop.operations, othertoken) args = [longlong.getfloatstorage(1.2), longlong.getfloatstorage(4.2)] deadframe = self.cpu.execute_token(othertoken, *args) @@ -3298,7 +3298,7 @@ looptoken = JitCellToken() looptoken.outermost_jitdriver_sd = FakeJitDriverSD() self.cpu.done_with_this_frame_descr_float = BasicFinalDescr() - self.cpu.compile_loop(None, loop.inputargs, loop.operations, looptoken) + self.cpu.compile_loop(loop.inputargs, loop.operations, looptoken) finish_descr = loop.operations[-1].getdescr() args = [longlong.getfloatstorage(1.25), longlong.getfloatstorage(2.35)] @@ -3315,7 +3315,7 @@ ''' loop = parse(ops, namespace=locals()) othertoken = JitCellToken() - self.cpu.compile_loop(None, loop.inputargs, loop.operations, othertoken) + self.cpu.compile_loop(loop.inputargs, loop.operations, othertoken) # normal call_assembler: goes to looptoken args = [longlong.getfloatstorage(1.25), @@ -3334,7 +3334,7 @@ loop2 = parse(ops) looptoken2 = JitCellToken() looptoken2.outermost_jitdriver_sd = FakeJitDriverSD() - self.cpu.compile_loop(None, loop2.inputargs, loop2.operations, looptoken2) + self.cpu.compile_loop(loop2.inputargs, loop2.operations, looptoken2) finish_descr2 = loop2.operations[-1].getdescr() # install it @@ -3694,7 +3694,7 @@ ] inputargs = [i0] looptoken = JitCellToken() - self.cpu.compile_loop(None, inputargs, operations, looptoken) + self.cpu.compile_loop(inputargs, operations, looptoken) # overflowing value: deadframe = self.cpu.execute_token(looptoken, sys.maxint // 4 + 1) fail = self.cpu.get_latest_descr(deadframe) @@ -3747,7 +3747,7 @@ operations[3].setfailargs([i1]) operations[6].setfailargs([i1]) - self.cpu.compile_loop(None, inputargs, operations, looptoken) + self.cpu.compile_loop(inputargs, operations, looptoken) deadframe = self.cpu.execute_token(looptoken, 2) fail = self.cpu.get_latest_descr(deadframe) assert fail.identifier == 2 @@ -3759,7 +3759,7 @@ ResOperation(rop.INT_SUB, [i0, ConstInt(20)], i2), ResOperation(rop.JUMP, [i2], None, descr=targettoken2), ] - self.cpu.compile_bridge(None, faildescr, inputargs2, operations2, looptoken) + self.cpu.compile_bridge(faildescr, inputargs2, operations2, looptoken) deadframe = self.cpu.execute_token(looptoken, 2) fail = self.cpu.get_latest_descr(deadframe) @@ -3776,7 +3776,7 @@ descr = BasicFinalDescr() loop = parse(ops, self.cpu, namespace=locals()) looptoken = JitCellToken() - self.cpu.compile_loop(None, loop.inputargs, loop.operations, looptoken) + self.cpu.compile_loop(loop.inputargs, loop.operations, looptoken) for inp, outp in [(2,2), (-3, 0)]: deadframe = self.cpu.execute_token(looptoken, inp) assert outp == self.cpu.get_int_value(deadframe, 0) @@ -3805,8 +3805,8 @@ bridge = parse(bridge_ops, self.cpu, namespace=locals()) looptoken = JitCellToken() self.cpu.assembler.set_debug(False) - info = self.cpu.compile_loop(None, loop.inputargs, loop.operations, looptoken) - bridge_info = self.cpu.compile_bridge(None, faildescr, bridge.inputargs, + info = self.cpu.compile_loop(loop.inputargs, loop.operations, looptoken) + bridge_info = self.cpu.compile_bridge(faildescr, bridge.inputargs, bridge.operations, looptoken) self.cpu.assembler.set_debug(True) # always on untranslated @@ -3850,7 +3850,7 @@ ResOperation(rop.FINISH, [i0], None, descr=BasicFinalDescr(1234)), ] operations[1].setfailargs([i0]) - self.cpu.compile_loop(None, inputargs, operations, looptoken1) + self.cpu.compile_loop(inputargs, operations, looptoken1) def func(a, b, c, d, e, f, g, h, i): assert a + 2 == b @@ -3904,14 +3904,14 @@ ResOperation(rop.JUMP, [i19], None, descr=targettoken1), ] operations2[-2].setfailargs([]) - self.cpu.compile_bridge(None, faildescr1, inputargs, operations2, looptoken1) + self.cpu.compile_bridge(faildescr1, inputargs, operations2, looptoken1) looptoken2 = JitCellToken() inputargs = [BoxInt()] operations3 = [ ResOperation(rop.JUMP, [ConstInt(0)], None, descr=targettoken1), ] - self.cpu.compile_loop(None, inputargs, operations3, looptoken2) + self.cpu.compile_loop(inputargs, operations3, looptoken2) deadframe = self.cpu.execute_token(looptoken2, -9) fail = self.cpu.get_latest_descr(deadframe) @@ -3928,11 +3928,11 @@ operations[0].setfailargs([]) looptoken = JitCellToken() inputargs = [t_box] - self.cpu.compile_loop(None, inputargs, operations, looptoken) + self.cpu.compile_loop(inputargs, operations, looptoken) operations = [ ResOperation(rop.FINISH, [], None, descr=BasicFinalDescr(99)) ] - self.cpu.compile_bridge(None, faildescr, [], operations, looptoken) + self.cpu.compile_bridge(faildescr, [], operations, looptoken) deadframe = self.cpu.execute_token(looptoken, null_box.getref_base()) fail = self.cpu.get_latest_descr(deadframe) assert fail.identifier == 99 @@ -3960,7 +3960,7 @@ # loop = parse(ops, self.cpu, namespace=locals()) looptoken = JitCellToken() - self.cpu.compile_loop(None, loop.inputargs, loop.operations, looptoken) + self.cpu.compile_loop(loop.inputargs, loop.operations, looptoken) deadframe = self.cpu.execute_token(looptoken, rffi.cast(lltype.Signed, p), 16) result = self.cpu.get_int_value(deadframe, 0) @@ -3990,7 +3990,7 @@ # loop = parse(ops, self.cpu, namespace=locals()) looptoken = JitCellToken() - self.cpu.compile_loop(None, loop.inputargs, loop.operations, looptoken) + self.cpu.compile_loop(loop.inputargs, loop.operations, looptoken) deadframe = self.cpu.execute_token(looptoken, rffi.cast(lltype.Signed, p), 16) result = self.cpu.get_float_value(deadframe, 0) @@ -4020,7 +4020,7 @@ # loop = parse(ops, self.cpu, namespace=locals()) looptoken = JitCellToken() - self.cpu.compile_loop(None, loop.inputargs, loop.operations, looptoken) + self.cpu.compile_loop(loop.inputargs, loop.operations, looptoken) deadframe = self.cpu.execute_token(looptoken, rffi.cast(lltype.Signed, p), 16) result = self.cpu.get_int_value(deadframe, 0) @@ -4052,7 +4052,7 @@ p[i] = '\xDD' loop = parse(ops, self.cpu, namespace=locals()) looptoken = JitCellToken() - self.cpu.compile_loop(None, loop.inputargs, loop.operations, looptoken) + self.cpu.compile_loop(loop.inputargs, loop.operations, looptoken) self.cpu.execute_token(looptoken, rffi.cast(lltype.Signed, p), 16, value) result = rawstorage.raw_storage_getitem(T, p, 16) @@ -4084,7 +4084,7 @@ p[i] = '\xDD' loop = parse(ops, self.cpu, namespace=locals()) looptoken = JitCellToken() - self.cpu.compile_loop(None, loop.inputargs, loop.operations, looptoken) + self.cpu.compile_loop(loop.inputargs, loop.operations, looptoken) self.cpu.execute_token(looptoken, rffi.cast(lltype.Signed, p), 16, longlong.getfloatstorage(value)) @@ -4118,7 +4118,7 @@ p[i] = '\xDD' loop = parse(ops, self.cpu, namespace=locals()) looptoken = JitCellToken() - self.cpu.compile_loop(None, loop.inputargs, loop.operations, looptoken) + self.cpu.compile_loop(loop.inputargs, loop.operations, looptoken) self.cpu.execute_token(looptoken, rffi.cast(lltype.Signed, p), 16, longlong.singlefloat2int(value)) @@ -4153,7 +4153,7 @@ ] ops[2].setfailargs([i2]) looptoken = JitCellToken() - self.cpu.compile_loop(None, [i0, i1], ops, looptoken) + self.cpu.compile_loop([i0, i1], ops, looptoken) deadframe = self.cpu.execute_token(looptoken, 20, 0) fail = self.cpu.get_latest_descr(deadframe) assert fail.identifier == 23 @@ -4187,7 +4187,7 @@ finish(i1, descr=finaldescr) """, namespace={'finaldescr': finaldescr, 'calldescr2': calldescr2, 'guarddescr': guarddescr, 'func2_ptr': func2_ptr}) - self.cpu.compile_bridge(None, faildescr, bridge.inputargs, + self.cpu.compile_bridge(faildescr, bridge.inputargs, bridge.operations, looptoken) cpu = self.cpu @@ -4220,7 +4220,7 @@ guard_true(i0, descr=faildescr) [i1, i2, px] finish(i2, descr=finaldescr2) """, namespace=locals()) - self.cpu.compile_loop(None, loop.inputargs, loop.operations, looptoken) + self.cpu.compile_loop(loop.inputargs, loop.operations, looptoken) frame = self.cpu.execute_token(looptoken, 0, 0, 3) assert self.cpu.get_latest_descr(frame) is guarddescr from rpython.jit.backend.llsupport.llmodel import AbstractLLCPU @@ -4269,7 +4269,7 @@ 'faildescr2': BasicFailDescr(1), 'xtp': xtp }) - self.cpu.compile_bridge(None, faildescr, bridge.inputargs, + self.cpu.compile_bridge(faildescr, bridge.inputargs, From noreply at buildbot.pypy.org Sun Sep 15 19:14:56 2013 From: noreply at buildbot.pypy.org (mattip) Date: Sun, 15 Sep 2013 19:14:56 +0200 (CEST) Subject: [pypy-commit] pypy safe-win-mmap: cleanup (amaury) Message-ID: <20130915171456.3B0E51C0162@cobra.cs.uni-duesseldorf.de> Author: mattip Branch: safe-win-mmap Changeset: r66959:8283a926aa30 Date: 2013-09-15 20:08 +0300 http://bitbucket.org/pypy/pypy/changeset/8283a926aa30/ Log: cleanup (amaury) diff --git a/rpython/rlib/rmmap.py b/rpython/rlib/rmmap.py --- a/rpython/rlib/rmmap.py +++ b/rpython/rlib/rmmap.py @@ -200,27 +200,16 @@ DuplicateHandle, _ = winexternal('DuplicateHandle', [HANDLE, HANDLE, HANDLE, LPHANDLE, DWORD, BOOL, DWORD], BOOL) CreateFileMapping, _ = winexternal('CreateFileMappingA', [HANDLE, rwin32.LPSECURITY_ATTRIBUTES, DWORD, DWORD, DWORD, LPCSTR], HANDLE) MapViewOfFile, _ = winexternal('MapViewOfFile', [HANDLE, DWORD, DWORD, DWORD, SIZE_T], LPCSTR)##!!LPVOID) - _, UnmapViewOfFile = winexternal('UnmapViewOfFile', [LPCSTR], BOOL) + _, UnmapViewOfFile_safe = winexternal('UnmapViewOfFile', [LPCSTR], BOOL) FlushViewOfFile, _ = winexternal('FlushViewOfFile', [LPCSTR, SIZE_T], BOOL) SetFilePointer, _ = winexternal('SetFilePointer', [HANDLE, LONG, PLONG, DWORD], DWORD) SetEndOfFile, _ = winexternal('SetEndOfFile', [HANDLE], BOOL) VirtualAlloc, VirtualAlloc_safe = winexternal('VirtualAlloc', [rffi.VOIDP, rffi.SIZE_T, DWORD, DWORD], rffi.VOIDP) - # VirtualProtect is used in llarena and should not release the GIL - _VirtualProtect, _ = winexternal('VirtualProtect', - [rffi.VOIDP, rffi.SIZE_T, DWORD, LPDWORD], - BOOL, - _nowrapper=True) _, VirtualProtect_safe = winexternal('VirtualProtect', [rffi.VOIDP, rffi.SIZE_T, DWORD, LPDWORD], BOOL) - def VirtualProtect(addr, size, mode, oldmode_ptr): - return _VirtualProtect(addr, - rffi.cast(rffi.SIZE_T, size), - rffi.cast(DWORD, mode), - oldmode_ptr) - VirtualProtect._annspecialcase_ = 'specialize:ll' VirtualFree, VirtualFree_safe = winexternal('VirtualFree', [rffi.VOIDP, rffi.SIZE_T, DWORD], BOOL) @@ -308,7 +297,7 @@ def unmap(self): if _MS_WINDOWS: - UnmapViewOfFile(self.getptr(0)) + UnmapViewOfFile_safe(self.getptr(0)) elif _POSIX: self.unmap_range(0, self.size) diff --git a/rpython/rtyper/lltypesystem/llarena.py b/rpython/rtyper/lltypesystem/llarena.py --- a/rpython/rtyper/lltypesystem/llarena.py +++ b/rpython/rtyper/lltypesystem/llarena.py @@ -529,13 +529,14 @@ elif os.name == 'nt': def llimpl_protect(addr, size, inaccessible): - from rpython.rlib.rmmap import VirtualProtect, LPDWORD + from rpython.rlib.rmmap import VirtualProtect_safe, LPDWORD if inaccessible: from rpython.rlib.rmmap import PAGE_NOACCESS as newprotect else: from rpython.rlib.rmmap import PAGE_READWRITE as newprotect arg = lltype.malloc(LPDWORD.TO, 1, zero=True, flavor='raw') - VirtualProtect(rffi.cast(rffi.VOIDP, addr), + #does not release the GIL + VirtualProtect_safe(rffi.cast(rffi.VOIDP, addr), size, newprotect, arg) # ignore potential errors lltype.free(arg, flavor='raw') From noreply at buildbot.pypy.org Sun Sep 15 20:11:48 2013 From: noreply at buildbot.pypy.org (mattip) Date: Sun, 15 Sep 2013 20:11:48 +0200 (CEST) Subject: [pypy-commit] pypy default: revert removal of c_memcpy Message-ID: <20130915181148.282951C10AE@cobra.cs.uni-duesseldorf.de> Author: mattip Branch: Changeset: r66960:59798bebed04 Date: 2013-09-15 21:06 +0300 http://bitbucket.org/pypy/pypy/changeset/59798bebed04/ Log: revert removal of c_memcpy diff --git a/rpython/rtyper/lltypesystem/rffi.py b/rpython/rtyper/lltypesystem/rffi.py --- a/rpython/rtyper/lltypesystem/rffi.py +++ b/rpython/rtyper/lltypesystem/rffi.py @@ -1132,3 +1132,12 @@ keep_unicodebuffer_alive_until_here(self.raw, self.gc_buf) def str(self, length): return unicode_from_buffer(self.raw, self.gc_buf, self.size, length) + +# You would have to have a *huge* amount of data for this to block long enough +# to be worth it to release the GIL. +c_memcpy = llexternal("memcpy", + [VOIDP, VOIDP, SIZE_T], + lltype.Void, + threadsafe=False + ) + From noreply at buildbot.pypy.org Sun Sep 15 20:11:49 2013 From: noreply at buildbot.pypy.org (mattip) Date: Sun, 15 Sep 2013 20:11:49 +0200 (CEST) Subject: [pypy-commit] pypy safe-win-mmap: merge default into branch Message-ID: <20130915181149.4F6F91C12EC@cobra.cs.uni-duesseldorf.de> Author: mattip Branch: safe-win-mmap Changeset: r66961:85f6662a9d4d Date: 2013-09-15 21:10 +0300 http://bitbucket.org/pypy/pypy/changeset/85f6662a9d4d/ Log: merge default into branch diff --git a/rpython/rtyper/lltypesystem/rffi.py b/rpython/rtyper/lltypesystem/rffi.py --- a/rpython/rtyper/lltypesystem/rffi.py +++ b/rpython/rtyper/lltypesystem/rffi.py @@ -1132,3 +1132,12 @@ keep_unicodebuffer_alive_until_here(self.raw, self.gc_buf) def str(self, length): return unicode_from_buffer(self.raw, self.gc_buf, self.size, length) + +# You would have to have a *huge* amount of data for this to block long enough +# to be worth it to release the GIL. +c_memcpy = llexternal("memcpy", + [VOIDP, VOIDP, SIZE_T], + lltype.Void, + threadsafe=False + ) + From noreply at buildbot.pypy.org Sun Sep 15 20:16:44 2013 From: noreply at buildbot.pypy.org (arigo) Date: Sun, 15 Sep 2013 20:16:44 +0200 (CEST) Subject: [pypy-commit] pypy default: Real fix Message-ID: <20130915181644.2A9B11C10AE@cobra.cs.uni-duesseldorf.de> Author: Armin Rigo Branch: Changeset: r66962:205f7bac272c Date: 2013-09-15 20:16 +0200 http://bitbucket.org/pypy/pypy/changeset/205f7bac272c/ Log: Real fix diff --git a/rpython/rtyper/lltypesystem/rffi.py b/rpython/rtyper/lltypesystem/rffi.py --- a/rpython/rtyper/lltypesystem/rffi.py +++ b/rpython/rtyper/lltypesystem/rffi.py @@ -1138,6 +1138,6 @@ c_memcpy = llexternal("memcpy", [VOIDP, VOIDP, SIZE_T], lltype.Void, - threadsafe=False + _nowrapper=True, releasegil=False ) From noreply at buildbot.pypy.org Sun Sep 15 20:20:28 2013 From: noreply at buildbot.pypy.org (fijal) Date: Sun, 15 Sep 2013 20:20:28 +0200 (CEST) Subject: [pypy-commit] extradoc extradoc: add my abstract Message-ID: <20130915182028.2B43E1C10AE@cobra.cs.uni-duesseldorf.de> Author: Maciej Fijalkowski Branch: extradoc Changeset: r5060:64321f53f40f Date: 2013-09-15 20:20 +0200 http://bitbucket.org/pypy/extradoc/changeset/64321f53f40f/ Log: add my abstract diff --git a/talk/pycon2014/benchmark-abstract.rst b/talk/pycon2014/benchmark-abstract.rst new file mode 100644 --- /dev/null +++ b/talk/pycon2014/benchmark-abstract.rst @@ -0,0 +1,48 @@ +How to benchmark your programs +------------------------------ + +Description +----------- + +Benchmarking is an important topic for software development. There is a lot +of research about how to do benchmarks carefully and correctly, however +a lot of people lack knowledge in this area as well as basic statistics. +This talk is aimed at sharing my knowledge about benchmarking the PyPy +project but the lessons learned should really apply to any software. + +Audience +-------- + +People interested in benchmarking. People who have performance problems +with their code. + +Objectives +---------- + +Attendees will learn some basic statistics, how to write benchmarks, how +to get reproducible data and how to avoid basic pitfalls with benchmarking. + +Detailed abstract +----------------- + +Benchmarking is hard. This talk is a way to share my knowledge that I +accumulated over the last few years while benchmarking various programs +on top of the PyPy project. It'll include benchmarking general programs, +using PyPy and CPython do get some data and postprocessing data. It'll also +include a brief guide of stuff I use for visualization. + +Outline +------- + +1. Intro, PyPy, background, 5min + +2. Background about benchmarking in general 10min. + +3. Commonly used tools. 10min + +4. Questions 5min + +Additional notes +---------------- + +PyPy benchmarking infrastructure is available under speed.pypy.org From noreply at buildbot.pypy.org Sun Sep 15 20:21:17 2013 From: noreply at buildbot.pypy.org (arigo) Date: Sun, 15 Sep 2013 20:21:17 +0200 (CEST) Subject: [pypy-commit] pypy default: Add a test for rffi.c_memcpy() Message-ID: <20130915182117.31C6E1C10AE@cobra.cs.uni-duesseldorf.de> Author: Armin Rigo Branch: Changeset: r66963:073ca086a2bf Date: 2013-09-15 20:20 +0200 http://bitbucket.org/pypy/pypy/changeset/073ca086a2bf/ Log: Add a test for rffi.c_memcpy() diff --git a/rpython/rtyper/lltypesystem/test/test_rffi.py b/rpython/rtyper/lltypesystem/test/test_rffi.py --- a/rpython/rtyper/lltypesystem/test/test_rffi.py +++ b/rpython/rtyper/lltypesystem/test/test_rffi.py @@ -810,3 +810,12 @@ assert cast(LONG, x) == 65535 else: assert cast(LONG, cast(INT, x)) == -1 + +def test_c_memcpy(): + p1 = str2charp("hello") + p2 = str2charp("WORLD") + c_memcpy(cast(VOIDP, p2), cast(VOIDP, p1), cast(SIZE_T, 3)) + assert charp2str(p1) == "hello" + assert charp2str(p2) == "helLD" + free_charp(p1) + free_charp(p2) From noreply at buildbot.pypy.org Sun Sep 15 20:24:05 2013 From: noreply at buildbot.pypy.org (arigo) Date: Sun, 15 Sep 2013 20:24:05 +0200 (CEST) Subject: [pypy-commit] pypy safe-win-mmap: hg merge default, again Message-ID: <20130915182405.9C0A51C10AE@cobra.cs.uni-duesseldorf.de> Author: Armin Rigo Branch: safe-win-mmap Changeset: r66964:e99ed373e5e7 Date: 2013-09-15 20:23 +0200 http://bitbucket.org/pypy/pypy/changeset/e99ed373e5e7/ Log: hg merge default, again diff --git a/rpython/rtyper/lltypesystem/rffi.py b/rpython/rtyper/lltypesystem/rffi.py --- a/rpython/rtyper/lltypesystem/rffi.py +++ b/rpython/rtyper/lltypesystem/rffi.py @@ -1138,6 +1138,6 @@ c_memcpy = llexternal("memcpy", [VOIDP, VOIDP, SIZE_T], lltype.Void, - threadsafe=False + _nowrapper=True, releasegil=False ) diff --git a/rpython/rtyper/lltypesystem/test/test_rffi.py b/rpython/rtyper/lltypesystem/test/test_rffi.py --- a/rpython/rtyper/lltypesystem/test/test_rffi.py +++ b/rpython/rtyper/lltypesystem/test/test_rffi.py @@ -810,3 +810,12 @@ assert cast(LONG, x) == 65535 else: assert cast(LONG, cast(INT, x)) == -1 + +def test_c_memcpy(): + p1 = str2charp("hello") + p2 = str2charp("WORLD") + c_memcpy(cast(VOIDP, p2), cast(VOIDP, p1), cast(SIZE_T, 3)) + assert charp2str(p1) == "hello" + assert charp2str(p2) == "helLD" + free_charp(p1) + free_charp(p2) From noreply at buildbot.pypy.org Sun Sep 15 20:28:26 2013 From: noreply at buildbot.pypy.org (arigo) Date: Sun, 15 Sep 2013 20:28:26 +0200 (CEST) Subject: [pypy-commit] extradoc extradoc: Typo Message-ID: <20130915182826.BFF1F1C10AE@cobra.cs.uni-duesseldorf.de> Author: Armin Rigo Branch: extradoc Changeset: r5061:24d4926368ac Date: 2013-09-15 20:28 +0200 http://bitbucket.org/pypy/extradoc/changeset/24d4926368ac/ Log: Typo diff --git a/talk/pycon2014/benchmark-abstract.rst b/talk/pycon2014/benchmark-abstract.rst --- a/talk/pycon2014/benchmark-abstract.rst +++ b/talk/pycon2014/benchmark-abstract.rst @@ -28,7 +28,7 @@ Benchmarking is hard. This talk is a way to share my knowledge that I accumulated over the last few years while benchmarking various programs on top of the PyPy project. It'll include benchmarking general programs, -using PyPy and CPython do get some data and postprocessing data. It'll also +using PyPy and CPython to get some data and postprocessing data. It'll also include a brief guide of stuff I use for visualization. Outline From noreply at buildbot.pypy.org Sun Sep 15 20:42:19 2013 From: noreply at buildbot.pypy.org (arigo) Date: Sun, 15 Sep 2013 20:42:19 +0200 (CEST) Subject: [pypy-commit] pypy default: Pfff, the wrapper is needed. Test showing it. Message-ID: <20130915184219.8F8031C0162@cobra.cs.uni-duesseldorf.de> Author: Armin Rigo Branch: Changeset: r66965:55b0874f6bd2 Date: 2013-09-15 20:41 +0200 http://bitbucket.org/pypy/pypy/changeset/55b0874f6bd2/ Log: Pfff, the wrapper is needed. Test showing it. diff --git a/rpython/rtyper/lltypesystem/rffi.py b/rpython/rtyper/lltypesystem/rffi.py --- a/rpython/rtyper/lltypesystem/rffi.py +++ b/rpython/rtyper/lltypesystem/rffi.py @@ -1138,6 +1138,5 @@ c_memcpy = llexternal("memcpy", [VOIDP, VOIDP, SIZE_T], lltype.Void, - _nowrapper=True, releasegil=False + releasegil=False ) - diff --git a/rpython/rtyper/lltypesystem/test/test_rffi.py b/rpython/rtyper/lltypesystem/test/test_rffi.py --- a/rpython/rtyper/lltypesystem/test/test_rffi.py +++ b/rpython/rtyper/lltypesystem/test/test_rffi.py @@ -814,7 +814,7 @@ def test_c_memcpy(): p1 = str2charp("hello") p2 = str2charp("WORLD") - c_memcpy(cast(VOIDP, p2), cast(VOIDP, p1), cast(SIZE_T, 3)) + c_memcpy(cast(VOIDP, p2), cast(VOIDP, p1), 3) assert charp2str(p1) == "hello" assert charp2str(p2) == "helLD" free_charp(p1) From noreply at buildbot.pypy.org Sun Sep 15 20:49:41 2013 From: noreply at buildbot.pypy.org (arigo) Date: Sun, 15 Sep 2013 20:49:41 +0200 (CEST) Subject: [pypy-commit] pypy safe-win-mmap: hg merge default Message-ID: <20130915184941.C17991C0162@cobra.cs.uni-duesseldorf.de> Author: Armin Rigo Branch: safe-win-mmap Changeset: r66966:d2932fe55f26 Date: 2013-09-15 20:48 +0200 http://bitbucket.org/pypy/pypy/changeset/d2932fe55f26/ Log: hg merge default diff --git a/rpython/rtyper/lltypesystem/rffi.py b/rpython/rtyper/lltypesystem/rffi.py --- a/rpython/rtyper/lltypesystem/rffi.py +++ b/rpython/rtyper/lltypesystem/rffi.py @@ -1138,6 +1138,5 @@ c_memcpy = llexternal("memcpy", [VOIDP, VOIDP, SIZE_T], lltype.Void, - _nowrapper=True, releasegil=False + releasegil=False ) - diff --git a/rpython/rtyper/lltypesystem/test/test_rffi.py b/rpython/rtyper/lltypesystem/test/test_rffi.py --- a/rpython/rtyper/lltypesystem/test/test_rffi.py +++ b/rpython/rtyper/lltypesystem/test/test_rffi.py @@ -814,7 +814,7 @@ def test_c_memcpy(): p1 = str2charp("hello") p2 = str2charp("WORLD") - c_memcpy(cast(VOIDP, p2), cast(VOIDP, p1), cast(SIZE_T, 3)) + c_memcpy(cast(VOIDP, p2), cast(VOIDP, p1), 3) assert charp2str(p1) == "hello" assert charp2str(p2) == "helLD" free_charp(p1) From noreply at buildbot.pypy.org Mon Sep 16 03:05:25 2013 From: noreply at buildbot.pypy.org (mattip) Date: Mon, 16 Sep 2013 03:05:25 +0200 (CEST) Subject: [pypy-commit] pypy safe-win-mmap: revert to fix translation Message-ID: <20130916010525.060801C0162@cobra.cs.uni-duesseldorf.de> Author: Matti Picus Branch: safe-win-mmap Changeset: r66967:5daf95147eb8 Date: 2013-09-16 04:00 +0300 http://bitbucket.org/pypy/pypy/changeset/5daf95147eb8/ Log: revert to fix translation diff --git a/rpython/rlib/rmmap.py b/rpython/rlib/rmmap.py --- a/rpython/rlib/rmmap.py +++ b/rpython/rlib/rmmap.py @@ -207,9 +207,15 @@ VirtualAlloc, VirtualAlloc_safe = winexternal('VirtualAlloc', [rffi.VOIDP, rffi.SIZE_T, DWORD, DWORD], rffi.VOIDP) - _, VirtualProtect_safe = winexternal('VirtualProtect', + _, _VirtualProtect_safe = winexternal('VirtualProtect', [rffi.VOIDP, rffi.SIZE_T, DWORD, LPDWORD], BOOL) + def VirtualProtect(addr, size, mode, oldmode_ptr): + return _VirtualProtect_safe(addr, + rffi.cast(rffi.SIZE_T, size), + rffi.cast(DWORD, mode), + oldmode_ptr) + VirtualProtect._annspecialcase_ = 'specialize:ll' VirtualFree, VirtualFree_safe = winexternal('VirtualFree', [rffi.VOIDP, rffi.SIZE_T, DWORD], BOOL) @@ -849,7 +855,7 @@ if not res: raise MemoryError arg = lltype.malloc(LPDWORD.TO, 1, zero=True, flavor='raw') - VirtualProtect_safe(res, map_size, PAGE_EXECUTE_READWRITE, arg) + VirtualProtect(res, map_size, PAGE_EXECUTE_READWRITE, arg) lltype.free(arg, flavor='raw') # ignore errors, just try return res diff --git a/rpython/rtyper/lltypesystem/llarena.py b/rpython/rtyper/lltypesystem/llarena.py --- a/rpython/rtyper/lltypesystem/llarena.py +++ b/rpython/rtyper/lltypesystem/llarena.py @@ -529,14 +529,14 @@ elif os.name == 'nt': def llimpl_protect(addr, size, inaccessible): - from rpython.rlib.rmmap import VirtualProtect_safe, LPDWORD + from rpython.rlib.rmmap import VirtualProtect, LPDWORD if inaccessible: from rpython.rlib.rmmap import PAGE_NOACCESS as newprotect else: from rpython.rlib.rmmap import PAGE_READWRITE as newprotect arg = lltype.malloc(LPDWORD.TO, 1, zero=True, flavor='raw') #does not release the GIL - VirtualProtect_safe(rffi.cast(rffi.VOIDP, addr), + VirtualProtect(rffi.cast(rffi.VOIDP, addr), size, newprotect, arg) # ignore potential errors lltype.free(arg, flavor='raw') From noreply at buildbot.pypy.org Mon Sep 16 21:13:51 2013 From: noreply at buildbot.pypy.org (mattip) Date: Mon, 16 Sep 2013 21:13:51 +0200 (CEST) Subject: [pypy-commit] pypy pypy-pyarray: comment, cleanup Message-ID: <20130916191351.8C3701C0113@cobra.cs.uni-duesseldorf.de> Author: Matti Picus Branch: pypy-pyarray Changeset: r66968:cc28a6c9e089 Date: 2013-09-13 00:10 +0300 http://bitbucket.org/pypy/pypy/changeset/cc28a6c9e089/ Log: comment, cleanup diff --git a/TODO.txt b/TODO.txt --- a/TODO.txt +++ b/TODO.txt @@ -9,13 +9,11 @@ - test "from numpypy import *" esp. get_include() - test all *.h files under pypy/module/cpyext/include/numpy -- make sure all cpyext changes are tested: - PyComplexFromCComplex() (changed, problematic for c++?) - _PyPackageContext (new) +- make sure meaningful cpyext changes are tested: all ndarrayobject.c copy_header_files() in api.py (changed) all ndarrayobject.py (new) - PyNumberCoerceEx() (new) - PyNumberCoerce() (new) + PyNumber_CoerceEx() (new) + PyNumber_Coerce() (new) - test, implement use of __array_prepare__() - test, implement use of __array_wrap__() diff --git a/pypy/module/cpyext/src/modsupport.c b/pypy/module/cpyext/src/modsupport.c --- a/pypy/module/cpyext/src/modsupport.c +++ b/pypy/module/cpyext/src/modsupport.c @@ -8,7 +8,9 @@ static PyObject *va_build_value(const char *, va_list, int); -/* Package context -- the full module name for package imports */ +/* Package context -- the full module name for package imports + * Should this be modified in _Py_InitPyPyModule for CPython + * compatibility (see CPython's Py_InitModule4)? */ char *_Py_PackageContext = NULL; /* Py_InitModule4() parameters: diff --git a/pypy/module/cpyext/test/test_number.py b/pypy/module/cpyext/test/test_number.py --- a/pypy/module/cpyext/test/test_number.py +++ b/pypy/module/cpyext/test/test_number.py @@ -43,7 +43,7 @@ ppf = lltype.malloc(PyObjectP.TO, 1, flavor='raw') ppl[0] = pl ppf[0] = pf - + ret = api.PyNumber_CoerceEx(ppl, ppf) assert ret == 0 @@ -55,7 +55,7 @@ Py_DecRef(space, ppf[0]) lltype.free(ppl, flavor='raw') lltype.free(ppf, flavor='raw') - + def test_numbermethods(self, space, api): assert "ab" == space.unwrap( api.PyNumber_Add(space.wrap("a"), space.wrap("b"))) From noreply at buildbot.pypy.org Mon Sep 16 21:13:52 2013 From: noreply at buildbot.pypy.org (mattip) Date: Mon, 16 Sep 2013 21:13:52 +0200 (CEST) Subject: [pypy-commit] pypy pypy-pyarray: refactor redundant function defs Message-ID: <20130916191352.C1BAF1C02FC@cobra.cs.uni-duesseldorf.de> Author: Matti Picus Branch: pypy-pyarray Changeset: r66969:d09d00f0417d Date: 2013-09-13 10:51 +0300 http://bitbucket.org/pypy/pypy/changeset/d09d00f0417d/ Log: refactor redundant function defs diff --git a/pypy/module/cpyext/number.py b/pypy/module/cpyext/number.py --- a/pypy/module/cpyext/number.py +++ b/pypy/module/cpyext/number.py @@ -58,8 +58,9 @@ @cpython_api([PyObjectP, PyObjectP], rffi.INT_real, error=-1) def PyNumber_CoerceEx(space, pp1, pp2): - """ - """ + """This function is similar to PyNumber_Coerce(), except that it returns + 1 when the conversion is not possible and when no error is raised. + Reference counts are still not increased in this case.""" w_obj1 = from_ref(space, pp1[0]) w_obj2 = from_ref(space, pp2[0]) w_res = space.try_coerce(w_obj1, w_obj2) @@ -74,13 +75,19 @@ @cpython_api([PyObjectP, PyObjectP], rffi.INT_real, error=-1) def PyNumber_Coerce(space, pp1, pp2): - """ - """ + """This function takes the addresses of two variables of type PyObject*. If + the objects pointed to by *p1 and *p2 have the same type, increment their + reference count and return 0 (success). If the objects can be converted to a + common numeric type, replace *p1 and *p2 by their converted value (with + 'new' reference counts), and return 0. If no conversion is possible, or if + some other error occurs, return -1 (failure) and don't increment the + reference counts. The call PyNumber_Coerce(&o1, &o2) is equivalent to the + Python statement o1, o2 = coerce(o1, o2).""" w_obj1 = from_ref(space, pp1[0]) w_obj2 = from_ref(space, pp2[0]) w_res = space.coerce(w_obj1, w_obj2) if w_res is None: - return 1 + return -1 else: Py_DecRef(space, pp1[0]) Py_DecRef(space, pp2[0]) 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 @@ -1528,25 +1528,6 @@ """ raise NotImplementedError - at cpython_api([PyObjectP, PyObjectP], rffi.INT_real, error=-1) -def PyNumber_Coerce(space, p1, p2): - """This function takes the addresses of two variables of type PyObject*. If - the objects pointed to by *p1 and *p2 have the same type, increment their - reference count and return 0 (success). If the objects can be converted to a - common numeric type, replace *p1 and *p2 by their converted value (with - 'new' reference counts), and return 0. If no conversion is possible, or if - some other error occurs, return -1 (failure) and don't increment the - reference counts. The call PyNumber_Coerce(&o1, &o2) is equivalent to the - Python statement o1, o2 = coerce(o1, o2).""" - raise NotImplementedError - - at cpython_api([PyObjectP, PyObjectP], rffi.INT_real, error=-1) -def PyNumber_CoerceEx(space, p1, p2): - """This function is similar to PyNumber_Coerce(), except that it returns - 1 when the conversion is not possible and when no error is raised. - Reference counts are still not increased in this case.""" - raise NotImplementedError - @cpython_api([PyObject, rffi.INT_real], PyObject) def PyNumber_ToBase(space, n, base): """Returns the integer n converted to base as a string with a base From noreply at buildbot.pypy.org Mon Sep 16 21:13:58 2013 From: noreply at buildbot.pypy.org (mattip) Date: Mon, 16 Sep 2013 21:13:58 +0200 (CEST) Subject: [pypy-commit] pypy boolean-indexing-cleanup: add test, fix for 1d view iteration in special boolean indexing case Message-ID: <20130916191358.A64791C1309@cobra.cs.uni-duesseldorf.de> Author: Matti Picus Branch: boolean-indexing-cleanup Changeset: r66974:427a21150489 Date: 2013-09-16 21:28 +0300 http://bitbucket.org/pypy/pypy/changeset/427a21150489/ Log: add test, fix for 1d view iteration in special boolean indexing case 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 @@ -386,7 +386,8 @@ loop.fill(self, box.convert_to(self.dtype)) def create_iter(self, shape=None, backward_broadcast=False): - if shape is not None and shape != self.get_shape(): + if shape is not None and shape != self.get_shape() and \ + support.product(shape) != support.product(self.get_shape()): r = calculate_broadcast_strides(self.get_strides(), self.get_backstrides(), self.get_shape(), shape, 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 @@ -2360,6 +2360,11 @@ b = arange(4).reshape(2, 2) + 10 a[a < 4] = b assert (a == [10, 11, 12, 13, 4, 5]).all() + b += 10 + c = arange(8).reshape(2, 2, 2) + a[a > 9] = c[:, :, 1] + assert (c[:, :, 1] == [[1, 3], [5, 7]]).all() + assert (a == [1, 3, 5, 7, 4, 5]).all() a = arange(6) a[a > 3] = array([15]) assert (a == [0, 1, 2, 3, 15, 15]).all() From noreply at buildbot.pypy.org Mon Sep 16 21:13:57 2013 From: noreply at buildbot.pypy.org (mattip) Date: Mon, 16 Sep 2013 21:13:57 +0200 (CEST) Subject: [pypy-commit] pypy boolean-indexing-cleanup: 'fix' boolean assignment by allowing creation of simple iterators if shape matches (numpy compatibility) Message-ID: <20130916191357.7E9251C0E26@cobra.cs.uni-duesseldorf.de> Author: Matti Picus Branch: boolean-indexing-cleanup Changeset: r66973:c206de17847f Date: 2013-09-16 21:07 +0300 http://bitbucket.org/pypy/pypy/changeset/c206de17847f/ Log: 'fix' boolean assignment by allowing creation of simple iterators if shape matches (numpy compatibility) 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 @@ -316,7 +316,8 @@ self.storage = storage def create_iter(self, shape=None, backward_broadcast=False): - if shape is None or shape == self.get_shape(): + if shape is None or \ + support.product(shape) == support.product(self.get_shape()): return iter.ConcreteArrayIterator(self) r = calculate_broadcast_strides(self.get_strides(), self.get_backstrides(), 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 @@ -97,13 +97,13 @@ space.wrap("index out of range for array")) idx_iter = idx.create_iter(self.get_shape()) size = loop.count_all_true_iter(idx_iter, self.get_shape(), idx.get_dtype()) - if len(val.get_shape()) > 0 and val.get_shape()[0] > 1 and size > val.get_shape()[0]: + if size != val.get_size() and val.get_size() > 1: raise OperationError(space.w_ValueError, space.wrap("NumPy boolean array indexing assignment " "cannot assign %d input values to " - "the %d output values where the mask is true" % (val.get_shape()[0],size))) + "the %d output values where the mask is true" % (val.get_size(), size))) if val.get_shape() == [0]: val.implementation.dtype = self.implementation.dtype - loop.setitem_filter(self, idx, val) + loop.setitem_filter(self, idx, val, size) def _prepare_array_index(self, space, w_index): if isinstance(w_index, W_NDimArray): 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 @@ -372,10 +372,10 @@ 'index_dtype'], reds = 'auto') -def setitem_filter(arr, index, value): +def setitem_filter(arr, index, value, size): arr_iter = arr.create_iter() index_iter = index.create_iter(arr.get_shape()) - value_iter = value.create_iter(arr.get_shape()) + value_iter = value.create_iter([size]) shapelen = len(arr.get_shape()) index_dtype = index.get_dtype() arr_dtype = arr.get_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 @@ -2355,11 +2355,11 @@ def test_array_indexing_bool_specialcases(self): from numpypy import arange, array a = arange(6) - try: - a[a < 3] = [1, 2] - assert False, "Should not work" - except ValueError: - pass + exc = raises(ValueError,'a[a < 3] = [1, 2]') + assert exc.value[0].find('cannot assign') >= 0 + b = arange(4).reshape(2, 2) + 10 + a[a < 4] = b + assert (a == [10, 11, 12, 13, 4, 5]).all() a = arange(6) a[a > 3] = array([15]) assert (a == [0, 1, 2, 3, 15, 15]).all() From noreply at buildbot.pypy.org Mon Sep 16 21:13:59 2013 From: noreply at buildbot.pypy.org (mattip) Date: Mon, 16 Sep 2013 21:13:59 +0200 (CEST) Subject: [pypy-commit] pypy boolean-indexing-cleanup: numpy allows boolean assignment mismatch, as long as there are more values on the rhs Message-ID: <20130916191359.D4D471C0113@cobra.cs.uni-duesseldorf.de> Author: Matti Picus Branch: boolean-indexing-cleanup Changeset: r66975:3dbf1e79be28 Date: 2013-09-16 22:12 +0300 http://bitbucket.org/pypy/pypy/changeset/3dbf1e79be28/ Log: numpy allows boolean assignment mismatch, as long as there are more values on the rhs 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 @@ -317,7 +317,7 @@ def create_iter(self, shape=None, backward_broadcast=False): if shape is None or \ - support.product(shape) == support.product(self.get_shape()): + support.product(shape) <= support.product(self.get_shape()): return iter.ConcreteArrayIterator(self) r = calculate_broadcast_strides(self.get_strides(), self.get_backstrides(), @@ -387,7 +387,7 @@ def create_iter(self, shape=None, backward_broadcast=False): if shape is not None and shape != self.get_shape() and \ - support.product(shape) != support.product(self.get_shape()): + support.product(shape) > support.product(self.get_shape()): r = calculate_broadcast_strides(self.get_strides(), self.get_backstrides(), self.get_shape(), shape, 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 @@ -97,7 +97,7 @@ space.wrap("index out of range for array")) idx_iter = idx.create_iter(self.get_shape()) size = loop.count_all_true_iter(idx_iter, self.get_shape(), idx.get_dtype()) - if size != val.get_size() and val.get_size() > 1: + if size > val.get_size() and val.get_size() > 1: raise OperationError(space.w_ValueError, space.wrap("NumPy boolean array indexing assignment " "cannot assign %d input values to " "the %d output values where the mask is true" % (val.get_size(), size))) From noreply at buildbot.pypy.org Mon Sep 16 21:13:53 2013 From: noreply at buildbot.pypy.org (mattip) Date: Mon, 16 Sep 2013 21:13:53 +0200 (CEST) Subject: [pypy-commit] pypy boolean-indexing-cleanup: a branch to fix boolean indexing which is failing tests (assert) Message-ID: <20130916191353.E2F661C0710@cobra.cs.uni-duesseldorf.de> Author: Matti Picus Branch: boolean-indexing-cleanup Changeset: r66970:034cc66ff910 Date: 2013-09-16 21:34 +0300 http://bitbucket.org/pypy/pypy/changeset/034cc66ff910/ Log: a branch to fix boolean indexing which is failing tests (assert) From noreply at buildbot.pypy.org Mon Sep 16 21:13:55 2013 From: noreply at buildbot.pypy.org (mattip) Date: Mon, 16 Sep 2013 21:13:55 +0200 (CEST) Subject: [pypy-commit] pypy boolean-indexing-cleanup: cleanup to remove failing assert Message-ID: <20130916191355.0E6B81C0842@cobra.cs.uni-duesseldorf.de> Author: Matti Picus Branch: boolean-indexing-cleanup Changeset: r66971:d5640e503ae5 Date: 2013-09-16 06:06 +0300 http://bitbucket.org/pypy/pypy/changeset/d5640e503ae5/ Log: cleanup to remove failing assert 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 @@ -88,9 +88,7 @@ w_res = W_NDimArray.from_shape(space, res_shape, self.get_dtype(), w_instance=self) return loop.getitem_filter(w_res, self, arr) - def setitem_filter(self, space, idx, value): - from pypy.module.micronumpy.interp_boxes import Box - val = value + def setitem_filter(self, space, idx, val): if len(idx.get_shape()) > 1 and idx.get_shape() != self.get_shape(): raise OperationError(space.w_ValueError, space.wrap("boolean index array should have 1 dimension")) @@ -103,11 +101,7 @@ raise OperationError(space.w_ValueError, space.wrap("NumPy boolean array indexing assignment " "cannot assign %d input values to " "the %d output values where the mask is true" % (val.get_shape()[0],size))) - if val.get_shape() == [1]: - box = val.descr_getitem(space, space.wrap(0)) - assert isinstance(box, Box) - val = W_NDimArray(scalar.Scalar(val.get_dtype(), box)) - elif val.get_shape() == [0]: + if val.get_shape() == [0]: val.implementation.dtype = self.implementation.dtype loop.setitem_filter(self, idx, val) From noreply at buildbot.pypy.org Mon Sep 16 21:13:56 2013 From: noreply at buildbot.pypy.org (mattip) Date: Mon, 16 Sep 2013 21:13:56 +0200 (CEST) Subject: [pypy-commit] pypy boolean-indexing-cleanup: build iter according to arr's shape Message-ID: <20130916191356.4FBEF1C0D8B@cobra.cs.uni-duesseldorf.de> Author: Matti Picus Branch: boolean-indexing-cleanup Changeset: r66972:f546fe80657f Date: 2013-09-16 20:02 +0300 http://bitbucket.org/pypy/pypy/changeset/f546fe80657f/ Log: build iter according to arr's shape 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 @@ -375,7 +375,7 @@ def setitem_filter(arr, index, value): arr_iter = arr.create_iter() index_iter = index.create_iter(arr.get_shape()) - value_iter = value.create_iter() + value_iter = value.create_iter(arr.get_shape()) shapelen = len(arr.get_shape()) index_dtype = index.get_dtype() arr_dtype = arr.get_dtype() From noreply at buildbot.pypy.org Mon Sep 16 21:18:34 2013 From: noreply at buildbot.pypy.org (mattip) Date: Mon, 16 Sep 2013 21:18:34 +0200 (CEST) Subject: [pypy-commit] pypy safe-win-mmap: document branch about to be merged Message-ID: <20130916191834.22C141C0113@cobra.cs.uni-duesseldorf.de> Author: Matti Picus Branch: safe-win-mmap Changeset: r66976:bdca70cb15d8 Date: 2013-09-16 22:15 +0300 http://bitbucket.org/pypy/pypy/changeset/bdca70cb15d8/ Log: document branch about to be merged 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 @@ -81,6 +81,7 @@ .. branch: numpypy-inplace-op .. branch: rewritten-loop-logging .. branch: no-release-gil +.. branch: safe-win-mmap .. branch: nobold-backtrace Work on improving UnionError messages and stack trace displays. From noreply at buildbot.pypy.org Mon Sep 16 21:18:35 2013 From: noreply at buildbot.pypy.org (mattip) Date: Mon, 16 Sep 2013 21:18:35 +0200 (CEST) Subject: [pypy-commit] pypy safe-win-mmap: close branch which fixes windows translation after no-release-gil merge Message-ID: <20130916191835.3E5621C0113@cobra.cs.uni-duesseldorf.de> Author: Matti Picus Branch: safe-win-mmap Changeset: r66977:c11afff751fa Date: 2013-09-16 22:16 +0300 http://bitbucket.org/pypy/pypy/changeset/c11afff751fa/ Log: close branch which fixes windows translation after no-release-gil merge From noreply at buildbot.pypy.org Mon Sep 16 21:18:36 2013 From: noreply at buildbot.pypy.org (mattip) Date: Mon, 16 Sep 2013 21:18:36 +0200 (CEST) Subject: [pypy-commit] pypy default: merge safe-win-mmap into default Message-ID: <20130916191836.8642E1C0113@cobra.cs.uni-duesseldorf.de> Author: Matti Picus Branch: Changeset: r66978:4c42c8e043b5 Date: 2013-09-16 22:17 +0300 http://bitbucket.org/pypy/pypy/changeset/4c42c8e043b5/ Log: merge safe-win-mmap into 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 @@ -81,6 +81,7 @@ .. branch: numpypy-inplace-op .. branch: rewritten-loop-logging .. branch: no-release-gil +.. branch: safe-win-mmap .. branch: nobold-backtrace Work on improving UnionError messages and stack trace displays. diff --git a/rpython/rlib/rmmap.py b/rpython/rlib/rmmap.py --- a/rpython/rlib/rmmap.py +++ b/rpython/rlib/rmmap.py @@ -118,10 +118,16 @@ return unsafe, safe def winexternal(name, args, result, **kwargs): - return rffi.llexternal(name, args, result, + unsafe = rffi.llexternal(name, args, result, compilation_info=CConfig._compilation_info_, calling_conv='win', **kwargs) + safe = rffi.llexternal(name, args, result, + compilation_info=CConfig._compilation_info_, + calling_conv='win', + sandboxsafe=True, releasegil=False, + **kwargs) + return unsafe, safe PTR = rffi.CCHARP @@ -188,32 +194,29 @@ SYSTEM_INFO = config['SYSTEM_INFO'] SYSTEM_INFO_P = lltype.Ptr(SYSTEM_INFO) - GetSystemInfo = winexternal('GetSystemInfo', [SYSTEM_INFO_P], lltype.Void) - GetFileSize = winexternal('GetFileSize', [HANDLE, LPDWORD], DWORD) - GetCurrentProcess = winexternal('GetCurrentProcess', [], HANDLE) - DuplicateHandle = winexternal('DuplicateHandle', [HANDLE, HANDLE, HANDLE, LPHANDLE, DWORD, BOOL, DWORD], BOOL) - CreateFileMapping = winexternal('CreateFileMappingA', [HANDLE, rwin32.LPSECURITY_ATTRIBUTES, DWORD, DWORD, DWORD, LPCSTR], HANDLE) - MapViewOfFile = winexternal('MapViewOfFile', [HANDLE, DWORD, DWORD, DWORD, SIZE_T], LPCSTR)##!!LPVOID) - UnmapViewOfFile = winexternal('UnmapViewOfFile', [LPCSTR], BOOL, - releasegil=False) - FlushViewOfFile = winexternal('FlushViewOfFile', [LPCSTR, SIZE_T], BOOL) - SetFilePointer = winexternal('SetFilePointer', [HANDLE, LONG, PLONG, DWORD], DWORD) - SetEndOfFile = winexternal('SetEndOfFile', [HANDLE], BOOL) - VirtualAlloc = winexternal('VirtualAlloc', + GetSystemInfo, _ = winexternal('GetSystemInfo', [SYSTEM_INFO_P], lltype.Void) + GetFileSize, _ = winexternal('GetFileSize', [HANDLE, LPDWORD], DWORD) + GetCurrentProcess, _ = winexternal('GetCurrentProcess', [], HANDLE) + DuplicateHandle, _ = winexternal('DuplicateHandle', [HANDLE, HANDLE, HANDLE, LPHANDLE, DWORD, BOOL, DWORD], BOOL) + CreateFileMapping, _ = winexternal('CreateFileMappingA', [HANDLE, rwin32.LPSECURITY_ATTRIBUTES, DWORD, DWORD, DWORD, LPCSTR], HANDLE) + MapViewOfFile, _ = winexternal('MapViewOfFile', [HANDLE, DWORD, DWORD, DWORD, SIZE_T], LPCSTR)##!!LPVOID) + _, UnmapViewOfFile_safe = winexternal('UnmapViewOfFile', [LPCSTR], BOOL) + FlushViewOfFile, _ = winexternal('FlushViewOfFile', [LPCSTR, SIZE_T], BOOL) + SetFilePointer, _ = winexternal('SetFilePointer', [HANDLE, LONG, PLONG, DWORD], DWORD) + SetEndOfFile, _ = winexternal('SetEndOfFile', [HANDLE], BOOL) + VirtualAlloc, VirtualAlloc_safe = winexternal('VirtualAlloc', [rffi.VOIDP, rffi.SIZE_T, DWORD, DWORD], rffi.VOIDP) - # VirtualProtect is used in llarena and should not release the GIL - _VirtualProtect = winexternal('VirtualProtect', + _, _VirtualProtect_safe = winexternal('VirtualProtect', [rffi.VOIDP, rffi.SIZE_T, DWORD, LPDWORD], - BOOL, - _nowrapper=True) + BOOL) def VirtualProtect(addr, size, mode, oldmode_ptr): - return _VirtualProtect(addr, + return _VirtualProtect_safe(addr, rffi.cast(rffi.SIZE_T, size), rffi.cast(DWORD, mode), oldmode_ptr) VirtualProtect._annspecialcase_ = 'specialize:ll' - VirtualFree = winexternal('VirtualFree', + VirtualFree, VirtualFree_safe = winexternal('VirtualFree', [rffi.VOIDP, rffi.SIZE_T, DWORD], BOOL) def _get_page_size(): @@ -300,7 +303,7 @@ def unmap(self): if _MS_WINDOWS: - UnmapViewOfFile(self.getptr(0)) + UnmapViewOfFile_safe(self.getptr(0)) elif _POSIX: self.unmap_range(0, self.size) @@ -575,6 +578,7 @@ def getitem(self, index): # simplified version, for rpython + self.check_valid() if index < 0: index += self.size return self.data[index] @@ -846,7 +850,7 @@ case of a sandboxed process """ null = lltype.nullptr(rffi.VOIDP.TO) - res = VirtualAlloc(null, map_size, MEM_COMMIT | MEM_RESERVE, + res = VirtualAlloc_safe(null, map_size, MEM_COMMIT | MEM_RESERVE, PAGE_EXECUTE_READWRITE) if not res: raise MemoryError @@ -858,6 +862,6 @@ alloc._annenforceargs_ = (int,) def free(ptr, map_size): - VirtualFree(ptr, 0, MEM_RELEASE) + VirtualFree_safe(ptr, 0, MEM_RELEASE) # register_external here? diff --git a/rpython/rtyper/lltypesystem/llarena.py b/rpython/rtyper/lltypesystem/llarena.py --- a/rpython/rtyper/lltypesystem/llarena.py +++ b/rpython/rtyper/lltypesystem/llarena.py @@ -535,6 +535,7 @@ else: from rpython.rlib.rmmap import PAGE_READWRITE as newprotect arg = lltype.malloc(LPDWORD.TO, 1, zero=True, flavor='raw') + #does not release the GIL VirtualProtect(rffi.cast(rffi.VOIDP, addr), size, newprotect, arg) # ignore potential errors diff --git a/rpython/rtyper/tool/rffi_platform.py b/rpython/rtyper/tool/rffi_platform.py --- a/rpython/rtyper/tool/rffi_platform.py +++ b/rpython/rtyper/tool/rffi_platform.py @@ -844,6 +844,10 @@ library_dir = '' libraries = ['gc64_dll'] includes = ['gc.h'] + # since config_external_library does not use a platform kwarg, + # somehow using a platform kw arg make the merge fail in + # config_external_library + platform = None else: library_dir = '' libraries = ['gc', 'dl'] From noreply at buildbot.pypy.org Mon Sep 16 23:21:12 2013 From: noreply at buildbot.pypy.org (mattip) Date: Mon, 16 Sep 2013 23:21:12 +0200 (CEST) Subject: [pypy-commit] pypy pypy-pyarray: add failing test (amaury) Message-ID: <20130916212112.768641C0842@cobra.cs.uni-duesseldorf.de> Author: Matti Picus Branch: pypy-pyarray Changeset: r66979:5d58d1a25800 Date: 2013-09-17 00:15 +0300 http://bitbucket.org/pypy/pypy/changeset/5d58d1a25800/ Log: add failing test (amaury) diff --git a/pypy/module/cpyext/test/test_number.py b/pypy/module/cpyext/test/test_number.py --- a/pypy/module/cpyext/test/test_number.py +++ b/pypy/module/cpyext/test/test_number.py @@ -1,8 +1,6 @@ -from rpython.rtyper.lltypesystem import rffi, lltype -from pypy.interpreter.error import OperationError +from rpython.rtyper.lltypesystem import lltype from pypy.module.cpyext.test.test_api import BaseApiTest -from pypy.module.cpyext import sequence -from pypy.module.cpyext.pyobject import PyObject, PyObjectP, from_ref, make_ref, Py_DecRef +from pypy.module.cpyext.pyobject import PyObjectP, from_ref, make_ref, Py_DecRef class TestIterator(BaseApiTest): def test_check(self, space, api): @@ -36,6 +34,24 @@ assert w_l is None api.PyErr_Clear() + def test_coerce(self, space, api): + w_obj1 = space.wrap(123) + w_obj2 = space.wrap(456.789) + pp1 = lltype.malloc(PyObjectP.TO, 1, flavor='raw') + pp1[0] = make_ref(space, w_obj1) + pp2 = lltype.malloc(PyObjectP.TO, 1, flavor='raw') + pp2[0] = make_ref(space, w_obj2) + assert api.PyNumber_Coerce(pp1, pp2) == 0 + assert space.str_w(space.repr(from_ref(space, pp1[0]))) == '123.0' + assert space.str_w(space.repr(from_ref(space, pp2[0]))) == '456.789' + Py_DecRef(space, pp1[0]) + Py_DecRef(space, pp2[0]) + # Yes, decrement twice. + Py_DecRef(space, w_obj1) + Py_DecRef(space, w_obj2) + lltype.free(pp1, flavor='raw') + lltype.free(pp2, flavor='raw') + def test_number_coerce_ex(self, space, api): pl = make_ref(space, space.wrap(123)) pf = make_ref(space, space.wrap(42.)) From noreply at buildbot.pypy.org Mon Sep 16 23:21:13 2013 From: noreply at buildbot.pypy.org (mattip) Date: Mon, 16 Sep 2013 23:21:13 +0200 (CEST) Subject: [pypy-commit] pypy boolean-indexing-cleanup: document branch that improves boolean indexing and fixes segfaulting test Message-ID: <20130916212113.C4FFC1C0842@cobra.cs.uni-duesseldorf.de> Author: Matti Picus Branch: boolean-indexing-cleanup Changeset: r66980:3ccfb152d844 Date: 2013-09-17 00:18 +0300 http://bitbucket.org/pypy/pypy/changeset/3ccfb152d844/ Log: document branch that improves boolean indexing and fixes segfaulting 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 @@ -81,6 +81,7 @@ .. branch: numpypy-inplace-op .. branch: rewritten-loop-logging .. branch: no-release-gil +.. branch: boolean-index-cleanup .. branch: nobold-backtrace Work on improving UnionError messages and stack trace displays. From noreply at buildbot.pypy.org Mon Sep 16 23:21:14 2013 From: noreply at buildbot.pypy.org (mattip) Date: Mon, 16 Sep 2013 23:21:14 +0200 (CEST) Subject: [pypy-commit] pypy boolean-indexing-cleanup: close branch to be merged Message-ID: <20130916212114.EDCA51C0842@cobra.cs.uni-duesseldorf.de> Author: Matti Picus Branch: boolean-indexing-cleanup Changeset: r66981:db6d3835c9bf Date: 2013-09-17 00:18 +0300 http://bitbucket.org/pypy/pypy/changeset/db6d3835c9bf/ Log: close branch to be merged From noreply at buildbot.pypy.org Mon Sep 16 23:21:16 2013 From: noreply at buildbot.pypy.org (mattip) Date: Mon, 16 Sep 2013 23:21:16 +0200 (CEST) Subject: [pypy-commit] pypy default: merge boolean-indexing-cleanup into default Message-ID: <20130916212116.2817F1C0842@cobra.cs.uni-duesseldorf.de> Author: Matti Picus Branch: Changeset: r66982:82db22721aa0 Date: 2013-09-17 00:19 +0300 http://bitbucket.org/pypy/pypy/changeset/82db22721aa0/ Log: merge boolean-indexing-cleanup into 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 @@ -82,6 +82,7 @@ .. branch: rewritten-loop-logging .. branch: no-release-gil .. branch: safe-win-mmap +.. branch: boolean-index-cleanup .. branch: nobold-backtrace Work on improving UnionError messages and stack trace displays. 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 @@ -316,7 +316,8 @@ self.storage = storage def create_iter(self, shape=None, backward_broadcast=False): - if shape is None or shape == self.get_shape(): + if shape is None or \ + support.product(shape) <= support.product(self.get_shape()): return iter.ConcreteArrayIterator(self) r = calculate_broadcast_strides(self.get_strides(), self.get_backstrides(), @@ -385,7 +386,8 @@ loop.fill(self, box.convert_to(self.dtype)) def create_iter(self, shape=None, backward_broadcast=False): - if shape is not None and shape != self.get_shape(): + if shape is not None and shape != self.get_shape() and \ + support.product(shape) > support.product(self.get_shape()): r = calculate_broadcast_strides(self.get_strides(), self.get_backstrides(), self.get_shape(), shape, 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 @@ -88,9 +88,7 @@ w_res = W_NDimArray.from_shape(space, res_shape, self.get_dtype(), w_instance=self) return loop.getitem_filter(w_res, self, arr) - def setitem_filter(self, space, idx, value): - from pypy.module.micronumpy.interp_boxes import Box - val = value + def setitem_filter(self, space, idx, val): if len(idx.get_shape()) > 1 and idx.get_shape() != self.get_shape(): raise OperationError(space.w_ValueError, space.wrap("boolean index array should have 1 dimension")) @@ -99,17 +97,13 @@ space.wrap("index out of range for array")) idx_iter = idx.create_iter(self.get_shape()) size = loop.count_all_true_iter(idx_iter, self.get_shape(), idx.get_dtype()) - if len(val.get_shape()) > 0 and val.get_shape()[0] > 1 and size > val.get_shape()[0]: + if size > val.get_size() and val.get_size() > 1: raise OperationError(space.w_ValueError, space.wrap("NumPy boolean array indexing assignment " "cannot assign %d input values to " - "the %d output values where the mask is true" % (val.get_shape()[0],size))) - if val.get_shape() == [1]: - box = val.descr_getitem(space, space.wrap(0)) - assert isinstance(box, Box) - val = W_NDimArray(scalar.Scalar(val.get_dtype(), box)) - elif val.get_shape() == [0]: + "the %d output values where the mask is true" % (val.get_size(), size))) + if val.get_shape() == [0]: val.implementation.dtype = self.implementation.dtype - loop.setitem_filter(self, idx, val) + loop.setitem_filter(self, idx, val, size) def _prepare_array_index(self, space, w_index): if isinstance(w_index, W_NDimArray): 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 @@ -372,10 +372,10 @@ 'index_dtype'], reds = 'auto') -def setitem_filter(arr, index, value): +def setitem_filter(arr, index, value, size): arr_iter = arr.create_iter() index_iter = index.create_iter(arr.get_shape()) - value_iter = value.create_iter() + value_iter = value.create_iter([size]) shapelen = len(arr.get_shape()) index_dtype = index.get_dtype() arr_dtype = arr.get_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 @@ -2355,11 +2355,16 @@ def test_array_indexing_bool_specialcases(self): from numpypy import arange, array a = arange(6) - try: - a[a < 3] = [1, 2] - assert False, "Should not work" - except ValueError: - pass + exc = raises(ValueError,'a[a < 3] = [1, 2]') + assert exc.value[0].find('cannot assign') >= 0 + b = arange(4).reshape(2, 2) + 10 + a[a < 4] = b + assert (a == [10, 11, 12, 13, 4, 5]).all() + b += 10 + c = arange(8).reshape(2, 2, 2) + a[a > 9] = c[:, :, 1] + assert (c[:, :, 1] == [[1, 3], [5, 7]]).all() + assert (a == [1, 3, 5, 7, 4, 5]).all() a = arange(6) a[a > 3] = array([15]) assert (a == [0, 1, 2, 3, 15, 15]).all() From noreply at buildbot.pypy.org Tue Sep 17 02:28:14 2013 From: noreply at buildbot.pypy.org (pjenvey) Date: Tue, 17 Sep 2013 02:28:14 +0200 (CEST) Subject: [pypy-commit] pypy py3k: adapt uuid optimizations from default to py3k Message-ID: <20130917002814.A666F1C0842@cobra.cs.uni-duesseldorf.de> Author: Philip Jenvey Branch: py3k Changeset: r66985:f2b132476063 Date: 2013-09-16 17:22 -0700 http://bitbucket.org/pypy/pypy/changeset/f2b132476063/ Log: adapt uuid optimizations from default to py3k diff --git a/lib-python/3/uuid.py b/lib-python/3/uuid.py --- a/lib-python/3/uuid.py +++ b/lib-python/3/uuid.py @@ -128,27 +128,39 @@ overriding the given 'hex', 'bytes', 'bytes_le', 'fields', or 'int'. """ - if [hex, bytes, bytes_le, fields, int].count(None) != 4: - raise TypeError('need one of hex, bytes, bytes_le, fields, or int') if hex is not None: + if (bytes is not None or bytes_le is not None or + fields is not None or int is not None): + raise TypeError('if the hex argument is given, bytes,' + ' bytes_le, fields, and int need to be None') hex = hex.replace('urn:', '').replace('uuid:', '') hex = hex.strip('{}').replace('-', '') if len(hex) != 32: raise ValueError('badly formed hexadecimal UUID string') int = int_(hex, 16) - if bytes_le is not None: + elif bytes_le is not None: + if bytes is not None or fields is not None or int is not None: + raise TypeError('if the bytes_le argument is given, bytes,' + ' fields, and int need to be None') if len(bytes_le) != 16: raise ValueError('bytes_le is not a 16-char string') bytes = (bytes_(reversed(bytes_le[0:4])) + bytes_(reversed(bytes_le[4:6])) + bytes_(reversed(bytes_le[6:8])) + bytes_le[8:]) - if bytes is not None: + int = int_.from_bytes(bytes, byteorder='big') + elif bytes is not None: + if fields is not None or int is not None: + raise TypeError('if the bytes argument is given, fields ' + 'and int need to be None') if len(bytes) != 16: raise ValueError('bytes is not a 16-char string') assert isinstance(bytes, bytes_), repr(bytes) - int = int_(('%02x'*16) % tuple(bytes), 16) - if fields is not None: + int = int_.from_bytes(bytes, byteorder='big') + elif fields is not None: + if int is not None: + raise TypeError('if the fields argument is given, int needs' + ' to be None') if len(fields) != 6: raise ValueError('fields is not a 6-tuple') (time_low, time_mid, time_hi_version, @@ -168,9 +180,12 @@ clock_seq = (clock_seq_hi_variant << 8) | clock_seq_low int = ((time_low << 96) | (time_mid << 80) | (time_hi_version << 64) | (clock_seq << 48) | node) - if int is not None: + elif int is not None: if not 0 <= int < 1<<128: raise ValueError('int is out of range (need a 128-bit value)') + else: + raise TypeError('one of hex, bytes, bytes_le, fields,' + ' or int need to be not None') if version is not None: if not 1 <= version <= 5: raise ValueError('illegal version number') @@ -180,7 +195,7 @@ # Set the version number. int &= ~(0xf000 << 64) int |= version << 76 - self.__dict__['int'] = int + object.__setattr__(self, 'int', int) def __eq__(self, other): if isinstance(other, UUID): From noreply at buildbot.pypy.org Tue Sep 17 02:28:10 2013 From: noreply at buildbot.pypy.org (pjenvey) Date: Tue, 17 Sep 2013 02:28:10 +0200 (CEST) Subject: [pypy-commit] pypy default: pep8 Message-ID: <20130917002810.BB3651C02FC@cobra.cs.uni-duesseldorf.de> Author: Philip Jenvey Branch: Changeset: r66983:7afcc006897c Date: 2013-09-16 16:42 -0700 http://bitbucket.org/pypy/pypy/changeset/7afcc006897c/ Log: pep8 diff --git a/lib-python/2.7/uuid.py b/lib-python/2.7/uuid.py --- a/lib-python/2.7/uuid.py +++ b/lib-python/2.7/uuid.py @@ -128,10 +128,10 @@ """ if hex is not None: - if (bytes is not None or bytes_le is not None or fields is not None - or int is not None): - raise TypeError('if the hex argument is given, bytes, bytes_le, fields,' - ' and int need to be None') + if (bytes is not None or bytes_le is not None or + fields is not None or int is not None): + raise TypeError('if the hex argument is given, bytes,' + ' bytes_le, fields, and int need to be None') hex = hex.replace('urn:', '').replace('uuid:', '') hex = hex.strip('{}').replace('-', '') if len(hex) != 32: @@ -139,8 +139,8 @@ int = long(hex, 16) elif bytes_le is not None: if bytes is not None or fields is not None or int is not None: - raise TypeError('if the bytes_le argument is given, bytes, fields,' - ' and int need to be None') + raise TypeError('if the bytes_le argument is given, bytes,' + ' fields, and int need to be None') if len(bytes_le) != 16: raise ValueError('bytes_le is not a 16-char string') bytes = (bytes_le[3] + bytes_le[2] + bytes_le[1] + bytes_le[0] + @@ -150,15 +150,16 @@ struct.unpack('>Q', bytes[8:])[0]) elif bytes is not None: if fields is not None or int is not None: - raise TypeError('if the bytes argument is given, fields' - ' and int need to be None') + raise TypeError('if the bytes argument is given, fields ' + 'and int need to be None') if len(bytes) != 16: raise ValueError('bytes is not a 16-char string') int = (struct.unpack('>Q', bytes[:8])[0] << 64 | struct.unpack('>Q', bytes[8:])[0]) elif fields is not None: if int is not None: - raise TypeError('if the fields argument is given, int needs to be None') + raise TypeError('if the fields argument is given, int needs' + ' to be None') if len(fields) != 6: raise ValueError('fields is not a 6-tuple') (time_low, time_mid, time_hi_version, From noreply at buildbot.pypy.org Tue Sep 17 02:28:13 2013 From: noreply at buildbot.pypy.org (pjenvey) Date: Tue, 17 Sep 2013 02:28:13 +0200 (CEST) Subject: [pypy-commit] pypy py3k: merge default Message-ID: <20130917002813.713F91C0710@cobra.cs.uni-duesseldorf.de> Author: Philip Jenvey Branch: py3k Changeset: r66984:77b4d8f086e7 Date: 2013-09-16 16:47 -0700 http://bitbucket.org/pypy/pypy/changeset/77b4d8f086e7/ Log: merge default diff too long, truncating to 2000 out of 3064 lines diff --git a/lib-python/2.7/uuid.py b/lib-python/2.7/uuid.py --- a/lib-python/2.7/uuid.py +++ b/lib-python/2.7/uuid.py @@ -128,10 +128,10 @@ """ if hex is not None: - if (bytes is not None or bytes_le is not None or fields is not None - or int is not None): - raise TypeError('if the hex argument is given, bytes, bytes_le, fields,' - ' and int need to be None') + if (bytes is not None or bytes_le is not None or + fields is not None or int is not None): + raise TypeError('if the hex argument is given, bytes,' + ' bytes_le, fields, and int need to be None') hex = hex.replace('urn:', '').replace('uuid:', '') hex = hex.strip('{}').replace('-', '') if len(hex) != 32: @@ -139,8 +139,8 @@ int = long(hex, 16) elif bytes_le is not None: if bytes is not None or fields is not None or int is not None: - raise TypeError('if the bytes_le argument is given, bytes, fields,' - ' and int need to be None') + raise TypeError('if the bytes_le argument is given, bytes,' + ' fields, and int need to be None') if len(bytes_le) != 16: raise ValueError('bytes_le is not a 16-char string') bytes = (bytes_le[3] + bytes_le[2] + bytes_le[1] + bytes_le[0] + @@ -150,15 +150,16 @@ struct.unpack('>Q', bytes[8:])[0]) elif bytes is not None: if fields is not None or int is not None: - raise TypeError('if the bytes argument is given, fields' - ' and int need to be None') + raise TypeError('if the bytes argument is given, fields ' + 'and int need to be None') if len(bytes) != 16: raise ValueError('bytes is not a 16-char string') int = (struct.unpack('>Q', bytes[:8])[0] << 64 | struct.unpack('>Q', bytes[8:])[0]) elif fields is not None: if int is not None: - raise TypeError('if the fields argument is given, int needs to be None') + raise TypeError('if the fields argument is given, int needs' + ' to be None') if len(fields) != 6: raise ValueError('fields is not a 6-tuple') (time_low, time_mid, time_hi_version, 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 @@ -81,6 +81,8 @@ .. branch: numpypy-inplace-op .. branch: rewritten-loop-logging .. branch: no-release-gil +.. branch: safe-win-mmap +.. branch: boolean-index-cleanup .. branch: nobold-backtrace Work on improving UnionError messages and stack trace displays. diff --git a/pypy/module/__pypy__/interp_time.py b/pypy/module/__pypy__/interp_time.py --- a/pypy/module/__pypy__/interp_time.py +++ b/pypy/module/__pypy__/interp_time.py @@ -48,11 +48,11 @@ c_clock_gettime = rffi.llexternal("clock_gettime", [lltype.Signed, lltype.Ptr(TIMESPEC)], rffi.INT, - compilation_info=CConfig._compilation_info_, threadsafe=False + compilation_info=CConfig._compilation_info_, releasegil=False ) c_clock_getres = rffi.llexternal("clock_getres", [lltype.Signed, lltype.Ptr(TIMESPEC)], rffi.INT, - compilation_info=CConfig._compilation_info_, threadsafe=False + compilation_info=CConfig._compilation_info_, releasegil=False ) @unwrap_spec(clk_id="c_int") 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 @@ -28,7 +28,7 @@ 'CreateSemaphoreA', [rffi.VOIDP, rffi.LONG, rffi.LONG, rwin32.LPCSTR], rwin32.HANDLE) _CloseHandle = rwin32.winexternal('CloseHandle', [rwin32.HANDLE], - rwin32.BOOL, threadsafe=False) + rwin32.BOOL, releasegil=False) _ReleaseSemaphore = rwin32.winexternal( 'ReleaseSemaphore', [rwin32.HANDLE, rffi.LONG, rffi.LONGP], rwin32.BOOL) @@ -82,8 +82,8 @@ _sem_open = external('sem_open', [rffi.CCHARP, rffi.INT, rffi.INT, rffi.UINT], SEM_T) - # tread sem_close as not threadsafe for now to be able to use the __del__ - _sem_close = external('sem_close', [SEM_T], rffi.INT, threadsafe=False) + # sem_close is releasegil=False to be able to use it in the __del__ + _sem_close = external('sem_close', [SEM_T], rffi.INT, releasegil=False) _sem_unlink = external('sem_unlink', [rffi.CCHARP], rffi.INT) _sem_wait = external('sem_wait', [SEM_T], rffi.INT) _sem_trywait = external('sem_trywait', [SEM_T], rffi.INT) 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 @@ -144,12 +144,12 @@ BZ2_bzCompressInit = external('BZ2_bzCompressInit', [bz_stream, rffi.INT, rffi.INT, rffi.INT], rffi.INT) BZ2_bzCompressEnd = external('BZ2_bzCompressEnd', [bz_stream], rffi.INT, - threadsafe=False) + releasegil=False) BZ2_bzCompress = external('BZ2_bzCompress', [bz_stream, rffi.INT], rffi.INT) BZ2_bzDecompressInit = external('BZ2_bzDecompressInit', [bz_stream, rffi.INT, rffi.INT], rffi.INT) BZ2_bzDecompressEnd = external('BZ2_bzDecompressEnd', [bz_stream], rffi.INT, - threadsafe=False) + releasegil=False) BZ2_bzDecompress = external('BZ2_bzDecompress', [bz_stream], rffi.INT) def _catch_bz2_error(space, bzerror): diff --git a/pypy/module/cppyy/capi/builtin_capi.py b/pypy/module/cppyy/capi/builtin_capi.py --- a/pypy/module/cppyy/capi/builtin_capi.py +++ b/pypy/module/cppyy/capi/builtin_capi.py @@ -27,7 +27,7 @@ _c_num_scopes = rffi.llexternal( "cppyy_num_scopes", [C_SCOPE], rffi.INT, - threadsafe=ts_reflect, + releasegil=ts_reflect, compilation_info=backend.eci) def c_num_scopes(space, cppscope): return _c_num_scopes(cppscope.handle) @@ -41,28 +41,28 @@ _c_resolve_name = rffi.llexternal( "cppyy_resolve_name", [rffi.CCHARP], rffi.CCHARP, - threadsafe=ts_reflect, + releasegil=ts_reflect, compilation_info=backend.eci) def c_resolve_name(space, name): return charp2str_free(space, _c_resolve_name(name)) _c_get_scope_opaque = rffi.llexternal( "cppyy_get_scope", [rffi.CCHARP], C_SCOPE, - threadsafe=ts_reflect, + releasegil=ts_reflect, compilation_info=backend.eci) def c_get_scope_opaque(space, name): return _c_get_scope_opaque(name) _c_get_template = rffi.llexternal( "cppyy_get_template", [rffi.CCHARP], C_TYPE, - threadsafe=ts_reflect, + releasegil=ts_reflect, compilation_info=backend.eci) def c_get_template(space, name): return _c_get_template(name) _c_actual_class = rffi.llexternal( "cppyy_actual_class", [C_TYPE, C_OBJECT], C_TYPE, - threadsafe=ts_reflect, + releasegil=ts_reflect, compilation_info=backend.eci) def c_actual_class(space, cppclass, cppobj): return _c_actual_class(cppclass.handle, cppobj) @@ -71,21 +71,21 @@ _c_allocate = rffi.llexternal( "cppyy_allocate", [C_TYPE], C_OBJECT, - threadsafe=ts_memory, + releasegil=ts_memory, compilation_info=backend.eci) def c_allocate(space, cppclass): return _c_allocate(cppclass.handle) _c_deallocate = rffi.llexternal( "cppyy_deallocate", [C_TYPE, C_OBJECT], lltype.Void, - threadsafe=ts_memory, + releasegil=ts_memory, compilation_info=backend.eci) def c_deallocate(space, cppclass, cppobject): _c_deallocate(cppclass.handle, cppobject) _c_destruct = rffi.llexternal( "cppyy_destruct", [C_TYPE, C_OBJECT], lltype.Void, - threadsafe=ts_call, + releasegil=ts_call, compilation_info=backend.eci) def c_destruct(space, cppclass, cppobject): _c_destruct(cppclass.handle, cppobject) @@ -94,63 +94,63 @@ _c_call_v = rffi.llexternal( "cppyy_call_v", [C_METHOD, C_OBJECT, rffi.INT, rffi.VOIDP], lltype.Void, - threadsafe=ts_call, + releasegil=ts_call, compilation_info=backend.eci) def c_call_v(space, cppmethod, cppobject, nargs, args): _c_call_v(cppmethod, cppobject, nargs, args) _c_call_b = rffi.llexternal( "cppyy_call_b", [C_METHOD, C_OBJECT, rffi.INT, rffi.VOIDP], rffi.UCHAR, - threadsafe=ts_call, + releasegil=ts_call, compilation_info=backend.eci) def c_call_b(space, cppmethod, cppobject, nargs, args): return _c_call_b(cppmethod, cppobject, nargs, args) _c_call_c = rffi.llexternal( "cppyy_call_c", [C_METHOD, C_OBJECT, rffi.INT, rffi.VOIDP], rffi.CHAR, - threadsafe=ts_call, + releasegil=ts_call, compilation_info=backend.eci) def c_call_c(space, cppmethod, cppobject, nargs, args): return _c_call_c(cppmethod, cppobject, nargs, args) _c_call_h = rffi.llexternal( "cppyy_call_h", [C_METHOD, C_OBJECT, rffi.INT, rffi.VOIDP], rffi.SHORT, - threadsafe=ts_call, + releasegil=ts_call, compilation_info=backend.eci) def c_call_h(space, cppmethod, cppobject, nargs, args): return _c_call_h(cppmethod, cppobject, nargs, args) _c_call_i = rffi.llexternal( "cppyy_call_i", [C_METHOD, C_OBJECT, rffi.INT, rffi.VOIDP], rffi.INT, - threadsafe=ts_call, + releasegil=ts_call, compilation_info=backend.eci) def c_call_i(space, cppmethod, cppobject, nargs, args): return _c_call_i(cppmethod, cppobject, nargs, args) _c_call_l = rffi.llexternal( "cppyy_call_l", [C_METHOD, C_OBJECT, rffi.INT, rffi.VOIDP], rffi.LONG, - threadsafe=ts_call, + releasegil=ts_call, compilation_info=backend.eci) def c_call_l(space, cppmethod, cppobject, nargs, args): return _c_call_l(cppmethod, cppobject, nargs, args) _c_call_ll = rffi.llexternal( "cppyy_call_ll", [C_METHOD, C_OBJECT, rffi.INT, rffi.VOIDP], rffi.LONGLONG, - threadsafe=ts_call, + releasegil=ts_call, compilation_info=backend.eci) def c_call_ll(space, cppmethod, cppobject, nargs, args): return _c_call_ll(cppmethod, cppobject, nargs, args) _c_call_f = rffi.llexternal( "cppyy_call_f", [C_METHOD, C_OBJECT, rffi.INT, rffi.VOIDP], rffi.FLOAT, - threadsafe=ts_call, + releasegil=ts_call, compilation_info=backend.eci) def c_call_f(space, cppmethod, cppobject, nargs, args): return _c_call_f(cppmethod, cppobject, nargs, args) _c_call_d = rffi.llexternal( "cppyy_call_d", [C_METHOD, C_OBJECT, rffi.INT, rffi.VOIDP], rffi.DOUBLE, - threadsafe=ts_call, + releasegil=ts_call, compilation_info=backend.eci) def c_call_d(space, cppmethod, cppobject, nargs, args): return _c_call_d(cppmethod, cppobject, nargs, args) @@ -158,14 +158,14 @@ _c_call_r = rffi.llexternal( "cppyy_call_r", [C_METHOD, C_OBJECT, rffi.INT, rffi.VOIDP], rffi.VOIDP, - threadsafe=ts_call, + releasegil=ts_call, compilation_info=backend.eci) def c_call_r(space, cppmethod, cppobject, nargs, args): return _c_call_r(cppmethod, cppobject, nargs, args) _c_call_s = rffi.llexternal( "cppyy_call_s", [C_METHOD, C_OBJECT, rffi.INT, rffi.VOIDP], rffi.CCHARP, - threadsafe=ts_call, + releasegil=ts_call, compilation_info=backend.eci) def c_call_s(space, cppmethod, cppobject, nargs, args): return _c_call_s(cppmethod, cppobject, nargs, args) @@ -173,14 +173,14 @@ _c_constructor = rffi.llexternal( "cppyy_constructor", [C_METHOD, C_TYPE, rffi.INT, rffi.VOIDP], C_OBJECT, - threadsafe=ts_call, + releasegil=ts_call, compilation_info=backend.eci) def c_constructor(space, cppmethod, cppobject, nargs, args): return _c_constructor(cppmethod, cppobject, nargs, args) _c_call_o = rffi.llexternal( "cppyy_call_o", [C_METHOD, C_OBJECT, rffi.INT, rffi.VOIDP, C_TYPE], rffi.LONG, - threadsafe=ts_call, + releasegil=ts_call, compilation_info=backend.eci) def c_call_o(space, method, cppobj, nargs, args, cppclass): return _c_call_o(method, cppobj, nargs, args, cppclass.handle) @@ -188,7 +188,7 @@ _c_get_methptr_getter = rffi.llexternal( "cppyy_get_methptr_getter", [C_SCOPE, C_INDEX], C_METHPTRGETTER_PTR, - threadsafe=ts_reflect, + releasegil=ts_reflect, compilation_info=backend.eci, elidable_function=True) def c_get_methptr_getter(space, cppscope, index): @@ -198,21 +198,21 @@ _c_allocate_function_args = rffi.llexternal( "cppyy_allocate_function_args", [rffi.SIZE_T], rffi.VOIDP, - threadsafe=ts_memory, + releasegil=ts_memory, compilation_info=backend.eci) def c_allocate_function_args(space, size): return _c_allocate_function_args(size) _c_deallocate_function_args = rffi.llexternal( "cppyy_deallocate_function_args", [rffi.VOIDP], lltype.Void, - threadsafe=ts_memory, + releasegil=ts_memory, compilation_info=backend.eci) def c_deallocate_function_args(space, args): _c_deallocate_function_args(args) _c_function_arg_sizeof = rffi.llexternal( "cppyy_function_arg_sizeof", [], rffi.SIZE_T, - threadsafe=ts_memory, + releasegil=ts_memory, compilation_info=backend.eci, elidable_function=True) def c_function_arg_sizeof(space): @@ -220,7 +220,7 @@ _c_function_arg_typeoffset = rffi.llexternal( "cppyy_function_arg_typeoffset", [], rffi.SIZE_T, - threadsafe=ts_memory, + releasegil=ts_memory, compilation_info=backend.eci, elidable_function=True) def c_function_arg_typeoffset(space): @@ -230,14 +230,14 @@ _c_is_namespace = rffi.llexternal( "cppyy_is_namespace", [C_SCOPE], rffi.INT, - threadsafe=ts_reflect, + releasegil=ts_reflect, compilation_info=backend.eci) def c_is_namespace(space, scope): return _c_is_namespace(scope) _c_is_enum = rffi.llexternal( "cppyy_is_enum", [rffi.CCHARP], rffi.INT, - threadsafe=ts_reflect, + releasegil=ts_reflect, compilation_info=backend.eci) def c_is_enum(space, name): return _c_is_enum(name) @@ -246,42 +246,42 @@ _c_final_name = rffi.llexternal( "cppyy_final_name", [C_TYPE], rffi.CCHARP, - threadsafe=ts_reflect, + releasegil=ts_reflect, compilation_info=backend.eci) def c_final_name(space, cpptype): return charp2str_free(space, _c_final_name(cpptype)) _c_scoped_final_name = rffi.llexternal( "cppyy_scoped_final_name", [C_TYPE], rffi.CCHARP, - threadsafe=ts_reflect, + releasegil=ts_reflect, compilation_info=backend.eci) def c_scoped_final_name(space, cpptype): return charp2str_free(space, _c_scoped_final_name(cpptype)) _c_has_complex_hierarchy = rffi.llexternal( "cppyy_has_complex_hierarchy", [C_TYPE], rffi.INT, - threadsafe=ts_reflect, + releasegil=ts_reflect, compilation_info=backend.eci) def c_has_complex_hierarchy(space, cpptype): return _c_has_complex_hierarchy(cpptype) _c_num_bases = rffi.llexternal( "cppyy_num_bases", [C_TYPE], rffi.INT, - threadsafe=ts_reflect, + releasegil=ts_reflect, compilation_info=backend.eci) def c_num_bases(space, cppclass): return _c_num_bases(cppclass.handle) _c_base_name = rffi.llexternal( "cppyy_base_name", [C_TYPE, rffi.INT], rffi.CCHARP, - threadsafe=ts_reflect, + releasegil=ts_reflect, compilation_info=backend.eci) def c_base_name(space, cppclass, base_index): return charp2str_free(space, _c_base_name(cppclass.handle, base_index)) _c_is_subtype = rffi.llexternal( "cppyy_is_subtype", [C_TYPE, C_TYPE], rffi.INT, - threadsafe=ts_reflect, + releasegil=ts_reflect, compilation_info=backend.eci, elidable_function=True) @jit.elidable_promote('2') @@ -293,7 +293,7 @@ _c_base_offset = rffi.llexternal( "cppyy_base_offset", [C_TYPE, C_TYPE, C_OBJECT, rffi.INT], rffi.SIZE_T, - threadsafe=ts_reflect, + releasegil=ts_reflect, compilation_info=backend.eci, elidable_function=True) @jit.elidable_promote('1,2,4') @@ -308,21 +308,21 @@ _c_num_methods = rffi.llexternal( "cppyy_num_methods", [C_SCOPE], rffi.INT, - threadsafe=ts_reflect, + releasegil=ts_reflect, compilation_info=backend.eci) def c_num_methods(space, cppscope): return _c_num_methods(cppscope.handle) _c_method_index_at = rffi.llexternal( "cppyy_method_index_at", [C_SCOPE, rffi.INT], C_INDEX, - threadsafe=ts_reflect, + releasegil=ts_reflect, compilation_info=backend.eci) def c_method_index_at(space, cppscope, imethod): return _c_method_index_at(cppscope.handle, imethod) _c_method_indices_from_name = rffi.llexternal( "cppyy_method_indices_from_name", [C_SCOPE, rffi.CCHARP], C_INDEX_ARRAY, - threadsafe=ts_reflect, + releasegil=ts_reflect, compilation_info=backend.eci) def c_method_indices_from_name(space, cppscope, name): indices = _c_method_indices_from_name(cppscope.handle, name) @@ -341,49 +341,49 @@ _c_method_name = rffi.llexternal( "cppyy_method_name", [C_SCOPE, C_INDEX], rffi.CCHARP, - threadsafe=ts_reflect, + releasegil=ts_reflect, compilation_info=backend.eci) def c_method_name(space, cppscope, index): return charp2str_free(space, _c_method_name(cppscope.handle, index)) _c_method_result_type = rffi.llexternal( "cppyy_method_result_type", [C_SCOPE, C_INDEX], rffi.CCHARP, - threadsafe=ts_reflect, + releasegil=ts_reflect, compilation_info=backend.eci) def c_method_result_type(space, cppscope, index): return charp2str_free(space, _c_method_result_type(cppscope.handle, index)) _c_method_num_args = rffi.llexternal( "cppyy_method_num_args", [C_SCOPE, C_INDEX], rffi.INT, - threadsafe=ts_reflect, + releasegil=ts_reflect, compilation_info=backend.eci) def c_method_num_args(space, cppscope, index): return _c_method_num_args(cppscope.handle, index) _c_method_req_args = rffi.llexternal( "cppyy_method_req_args", [C_SCOPE, C_INDEX], rffi.INT, - threadsafe=ts_reflect, + releasegil=ts_reflect, compilation_info=backend.eci) def c_method_req_args(space, cppscope, index): return _c_method_req_args(cppscope.handle, index) _c_method_arg_type = rffi.llexternal( "cppyy_method_arg_type", [C_SCOPE, C_INDEX, rffi.INT], rffi.CCHARP, - threadsafe=ts_reflect, + releasegil=ts_reflect, compilation_info=backend.eci) def c_method_arg_type(space, cppscope, index, arg_index): return charp2str_free(space, _c_method_arg_type(cppscope.handle, index, arg_index)) _c_method_arg_default = rffi.llexternal( "cppyy_method_arg_default", [C_SCOPE, C_INDEX, rffi.INT], rffi.CCHARP, - threadsafe=ts_reflect, + releasegil=ts_reflect, compilation_info=backend.eci) def c_method_arg_default(space, cppscope, index, arg_index): return charp2str_free(space, _c_method_arg_default(cppscope.handle, index, arg_index)) _c_method_signature = rffi.llexternal( "cppyy_method_signature", [C_SCOPE, C_INDEX], rffi.CCHARP, - threadsafe=ts_reflect, + releasegil=ts_reflect, compilation_info=backend.eci) def c_method_signature(space, cppscope, index): return charp2str_free(space, _c_method_signature(cppscope.handle, index)) @@ -391,19 +391,19 @@ _c_method_is_template = rffi.llexternal( "cppyy_method_is_template", [C_SCOPE, C_INDEX], rffi.INT, - threadsafe=ts_reflect, + releasegil=ts_reflect, compilation_info=backend.eci) def c_method_is_template(space, 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, + releasegil=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, + releasegil=ts_reflect, compilation_info=backend.eci) def c_template_args(space, cppscope, index): nargs = _c_method_num_template_args(cppscope.handle, index) @@ -415,14 +415,14 @@ _c_get_method = rffi.llexternal( "cppyy_get_method", [C_SCOPE, C_INDEX], C_METHOD, - threadsafe=ts_reflect, + releasegil=ts_reflect, compilation_info=backend.eci) def c_get_method(space, cppscope, index): return _c_get_method(cppscope.handle, index) _c_get_global_operator = rffi.llexternal( "cppyy_get_global_operator", [C_SCOPE, C_SCOPE, C_SCOPE, rffi.CCHARP], WLAVC_INDEX, - threadsafe=ts_reflect, + releasegil=ts_reflect, compilation_info=backend.eci) def c_get_global_operator(space, nss, lc, rc, op): if nss is not None: @@ -433,14 +433,14 @@ _c_is_constructor = rffi.llexternal( "cppyy_is_constructor", [C_TYPE, C_INDEX], rffi.INT, - threadsafe=ts_reflect, + releasegil=ts_reflect, compilation_info=backend.eci) def c_is_constructor(space, cppclass, index): return _c_is_constructor(cppclass.handle, index) _c_is_staticmethod = rffi.llexternal( "cppyy_is_staticmethod", [C_TYPE, C_INDEX], rffi.INT, - threadsafe=ts_reflect, + releasegil=ts_reflect, compilation_info=backend.eci) def c_is_staticmethod(space, cppclass, index): return _c_is_staticmethod(cppclass.handle, index) @@ -449,28 +449,28 @@ _c_num_datamembers = rffi.llexternal( "cppyy_num_datamembers", [C_SCOPE], rffi.INT, - threadsafe=ts_reflect, + releasegil=ts_reflect, compilation_info=backend.eci) def c_num_datamembers(space, cppscope): return _c_num_datamembers(cppscope.handle) _c_datamember_name = rffi.llexternal( "cppyy_datamember_name", [C_SCOPE, rffi.INT], rffi.CCHARP, - threadsafe=ts_reflect, + releasegil=ts_reflect, compilation_info=backend.eci) def c_datamember_name(space, cppscope, datamember_index): return charp2str_free(space, _c_datamember_name(cppscope.handle, datamember_index)) _c_datamember_type = rffi.llexternal( "cppyy_datamember_type", [C_SCOPE, rffi.INT], rffi.CCHARP, - threadsafe=ts_reflect, + releasegil=ts_reflect, compilation_info=backend.eci) def c_datamember_type(space, cppscope, datamember_index): return charp2str_free(space, _c_datamember_type(cppscope.handle, datamember_index)) _c_datamember_offset = rffi.llexternal( "cppyy_datamember_offset", [C_SCOPE, rffi.INT], rffi.SIZE_T, - threadsafe=ts_reflect, + releasegil=ts_reflect, compilation_info=backend.eci) def c_datamember_offset(space, cppscope, datamember_index): return _c_datamember_offset(cppscope.handle, datamember_index) @@ -478,7 +478,7 @@ _c_datamember_index = rffi.llexternal( "cppyy_datamember_index", [C_SCOPE, rffi.CCHARP], rffi.INT, - threadsafe=ts_reflect, + releasegil=ts_reflect, compilation_info=backend.eci) def c_datamember_index(space, cppscope, name): return _c_datamember_index(cppscope.handle, name) @@ -487,14 +487,14 @@ _c_is_publicdata = rffi.llexternal( "cppyy_is_publicdata", [C_SCOPE, rffi.INT], rffi.INT, - threadsafe=ts_reflect, + releasegil=ts_reflect, compilation_info=backend.eci) def c_is_publicdata(space, cppscope, datamember_index): return _c_is_publicdata(cppscope.handle, datamember_index) _c_is_staticdata = rffi.llexternal( "cppyy_is_staticdata", [C_SCOPE, rffi.INT], rffi.INT, - threadsafe=ts_reflect, + releasegil=ts_reflect, compilation_info=backend.eci) def c_is_staticdata(space, cppscope, datamember_index): return _c_is_staticdata(cppscope.handle, datamember_index) @@ -503,21 +503,21 @@ _c_strtoll = rffi.llexternal( "cppyy_strtoll", [rffi.CCHARP], rffi.LONGLONG, - threadsafe=ts_helper, + releasegil=ts_helper, compilation_info=backend.eci) def c_strtoll(space, svalue): return _c_strtoll(svalue) _c_strtoull = rffi.llexternal( "cppyy_strtoull", [rffi.CCHARP], rffi.ULONGLONG, - threadsafe=ts_helper, + releasegil=ts_helper, compilation_info=backend.eci) def c_strtoull(space, svalue): return _c_strtoull(svalue) c_free = rffi.llexternal( "cppyy_free", [rffi.VOIDP], lltype.Void, - threadsafe=ts_memory, + releasegil=ts_memory, compilation_info=backend.eci) def charp2str_free(space, charp): @@ -529,7 +529,7 @@ _c_charp2stdstring = rffi.llexternal( "cppyy_charp2stdstring", [rffi.CCHARP], C_OBJECT, - threadsafe=ts_helper, + releasegil=ts_helper, compilation_info=backend.eci) def c_charp2stdstring(space, svalue): charp = rffi.str2charp(svalue) @@ -539,14 +539,14 @@ _c_stdstring2stdstring = rffi.llexternal( "cppyy_stdstring2stdstring", [C_OBJECT], C_OBJECT, - threadsafe=ts_helper, + releasegil=ts_helper, compilation_info=backend.eci) def c_stdstring2stdstring(space, cppobject): return _c_stdstring2stdstring(cppobject) _c_assign2stdstring = rffi.llexternal( "cppyy_assign2stdstring", [C_OBJECT, rffi.CCHARP], lltype.Void, - threadsafe=ts_helper, + releasegil=ts_helper, compilation_info=backend.eci) def c_assign2stdstring(space, cppobject, svalue): charp = rffi.str2charp(svalue) @@ -555,7 +555,7 @@ _c_free_stdstring = rffi.llexternal( "cppyy_free_stdstring", [C_OBJECT], lltype.Void, - threadsafe=ts_helper, + releasegil=ts_helper, compilation_info=backend.eci) def c_free_stdstring(space, cppobject): _c_free_stdstring(cppobject) 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 @@ -60,7 +60,7 @@ _c_load_dictionary = rffi.llexternal( "cppyy_load_dictionary", [rffi.CCHARP], rdynload.DLLHANDLE, - threadsafe=False, + releasegil=False, compilation_info=eci) def c_load_dictionary(name): @@ -84,7 +84,7 @@ _ttree_Branch = rffi.llexternal( "cppyy_ttree_Branch", [rffi.VOIDP, rffi.CCHARP, rffi.CCHARP, rffi.VOIDP, rffi.INT, rffi.INT], rffi.LONG, - threadsafe=False, + releasegil=False, compilation_info=eci) @unwrap_spec(args_w='args_w') @@ -158,7 +158,7 @@ c_ttree_GetEntry = rffi.llexternal( "cppyy_ttree_GetEntry", [rffi.VOIDP, rffi.LONGLONG], rffi.LONGLONG, - threadsafe=False, + releasegil=False, compilation_info=eci) @unwrap_spec(args_w='args_w') diff --git a/pypy/module/crypt/interp_crypt.py b/pypy/module/crypt/interp_crypt.py --- a/pypy/module/crypt/interp_crypt.py +++ b/pypy/module/crypt/interp_crypt.py @@ -8,7 +8,7 @@ else: eci = ExternalCompilationInfo(libraries=['crypt']) c_crypt = rffi.llexternal('crypt', [rffi.CCHARP, rffi.CCHARP], rffi.CCHARP, - compilation_info=eci, threadsafe=False) + compilation_info=eci, releasegil=False) @unwrap_spec(word=str, salt=str) def crypt(space, word, salt): 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 @@ -316,7 +316,8 @@ self.storage = storage def create_iter(self, shape=None, backward_broadcast=False): - if shape is None or shape == self.get_shape(): + if shape is None or \ + support.product(shape) <= support.product(self.get_shape()): return iter.ConcreteArrayIterator(self) r = calculate_broadcast_strides(self.get_strides(), self.get_backstrides(), @@ -385,7 +386,8 @@ loop.fill(self, box.convert_to(self.dtype)) def create_iter(self, shape=None, backward_broadcast=False): - if shape is not None and shape != self.get_shape(): + if shape is not None and shape != self.get_shape() and \ + support.product(shape) > support.product(self.get_shape()): r = calculate_broadcast_strides(self.get_strides(), self.get_backstrides(), self.get_shape(), shape, 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 @@ -88,9 +88,7 @@ w_res = W_NDimArray.from_shape(space, res_shape, self.get_dtype(), w_instance=self) return loop.getitem_filter(w_res, self, arr) - def setitem_filter(self, space, idx, value): - from pypy.module.micronumpy.interp_boxes import Box - val = value + def setitem_filter(self, space, idx, val): if len(idx.get_shape()) > 1 and idx.get_shape() != self.get_shape(): raise OperationError(space.w_ValueError, space.wrap("boolean index array should have 1 dimension")) @@ -99,17 +97,13 @@ space.wrap("index out of range for array")) idx_iter = idx.create_iter(self.get_shape()) size = loop.count_all_true_iter(idx_iter, self.get_shape(), idx.get_dtype()) - if len(val.get_shape()) > 0 and val.get_shape()[0] > 1 and size > val.get_shape()[0]: + if size > val.get_size() and val.get_size() > 1: raise OperationError(space.w_ValueError, space.wrap("NumPy boolean array indexing assignment " "cannot assign %d input values to " - "the %d output values where the mask is true" % (val.get_shape()[0],size))) - if val.get_shape() == [1]: - box = val.descr_getitem(space, space.wrap(0)) - assert isinstance(box, Box) - val = W_NDimArray(scalar.Scalar(val.get_dtype(), box)) - elif val.get_shape() == [0]: + "the %d output values where the mask is true" % (val.get_size(), size))) + if val.get_shape() == [0]: val.implementation.dtype = self.implementation.dtype - loop.setitem_filter(self, idx, val) + loop.setitem_filter(self, idx, val, size) def _prepare_array_index(self, space, w_index): if isinstance(w_index, W_NDimArray): 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 @@ -372,10 +372,10 @@ 'index_dtype'], reds = 'auto') -def setitem_filter(arr, index, value): +def setitem_filter(arr, index, value, size): arr_iter = arr.create_iter() index_iter = index.create_iter(arr.get_shape()) - value_iter = value.create_iter() + value_iter = value.create_iter([size]) shapelen = len(arr.get_shape()) index_dtype = index.get_dtype() arr_dtype = arr.get_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 @@ -775,7 +775,13 @@ def test_unicode_boxes(self): from numpypy import unicode_ - assert isinstance(unicode_(3), str) + try: + u = unicode_(3) + except NotImplementedError as e: + if e.message.find('not supported yet') >= 0: + skip('unicode box not implemented') + else: + assert isinstance(u, str) def test_character_dtype(self): from numpypy import array, character 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 @@ -2355,11 +2355,16 @@ def test_array_indexing_bool_specialcases(self): from numpypy import arange, array a = arange(6) - try: - a[a < 3] = [1, 2] - assert False, "Should not work" - except ValueError: - pass + exc = raises(ValueError,'a[a < 3] = [1, 2]') + assert exc.value[0].find('cannot assign') >= 0 + b = arange(4).reshape(2, 2) + 10 + a[a < 4] = b + assert (a == [10, 11, 12, 13, 4, 5]).all() + b += 10 + c = arange(8).reshape(2, 2, 2) + a[a > 9] = c[:, :, 1] + assert (c[:, :, 1] == [[1, 3], [5, 7]]).all() + assert (a == [1, 3, 5, 7, 4, 5]).all() a = arange(6) a[a > 3] = array([15]) assert (a == [0, 1, 2, 3, 15, 15]).all() 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 @@ -356,7 +356,7 @@ XML_ParserCreateNS = expat_external( 'XML_ParserCreateNS', [rffi.CCHARP, rffi.CHAR], XML_Parser) XML_ParserFree = expat_external( - 'XML_ParserFree', [XML_Parser], lltype.Void, threadsafe=False) + 'XML_ParserFree', [XML_Parser], lltype.Void, releasegil=False) XML_SetUserData = expat_external( 'XML_SetUserData', [XML_Parser, rffi.VOIDP], lltype.Void) def XML_GetUserData(parser): 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 @@ -151,7 +151,7 @@ return rffi.llexternal(name, args, result, compilation_info=eci, calling_conv=calling_conv, - threadsafe=False) + releasegil=False) if _POSIX: cConfig.timeval.__name__ = "_timeval" diff --git a/pypy/module/test_lib_pypy/test_resource.py b/pypy/module/test_lib_pypy/test_resource.py --- a/pypy/module/test_lib_pypy/test_resource.py +++ b/pypy/module/test_lib_pypy/test_resource.py @@ -3,6 +3,9 @@ from lib_pypy.ctypes_config_cache import rebuild from pypy.module.test_lib_pypy.support import import_lib_pypy +import os +if os.name != 'posix': + skip('resource.h only available on unix') class AppTestResource: 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 @@ -56,13 +56,13 @@ def finish_once(self): self.assembler.finish_once() - def compile_loop(self, logger, inputargs, operations, looptoken, - log=True, name=''): + def compile_loop(self, inputargs, operations, looptoken, + log=True, name='', logger=None): return self.assembler.assemble_loop(logger, name, inputargs, operations, looptoken, log=log) - def compile_bridge(self, logger, faildescr, inputargs, operations, - original_loop_token, log=True): + def compile_bridge(self, faildescr, inputargs, operations, + original_loop_token, log=True, logger=None): clt = original_loop_token.compiled_loop_token clt.compiling_a_bridge() return self.assembler.assemble_bridge(logger, faildescr, inputargs, 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 @@ -40,7 +40,7 @@ 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(None, inputargs, operations, looptoken) + cpu.compile_loop(inputargs, operations, looptoken) args = [-12 , -26 , -19 , 7 , -5 , -24 , -37 , 62 , 9 , 12] deadframe = cpu.execute_token(looptoken, *args) assert cpu.get_int_value(deadframe, 0) == 0 @@ -92,7 +92,7 @@ operations[9].setfailargs([v15, v7, v10, v18, v4, v17, v1]) operations[-1].setfailargs([v7, v1, v2]) looptoken = JitCellToken() - cpu.compile_loop(None, inputargs, operations, looptoken) + cpu.compile_loop(inputargs, operations, looptoken) args = [16 , 5 , 5 , 16 , 46 , 6 , 63 , 39 , 78 , 0] deadframe = cpu.execute_token(looptoken, *args) assert cpu.get_int_value(deadframe, 0) == 105 @@ -136,7 +136,7 @@ operations[-1].setfailargs([v5, v2, v1, v10, v3, v8, v4, v6]) looptoken = JitCellToken() - cpu.compile_loop(None, inputargs, operations, looptoken) + cpu.compile_loop(inputargs, operations, looptoken) args = [-5 , 24 , 46 , -15 , 13 , -8 , 0 , -6 , 6 , 6] deadframe = cpu.execute_token(looptoken, *args) assert cpu.get_latest_descr(deadframe).identifier == 2 @@ -179,7 +179,7 @@ operations[5].setfailargs([]) operations[-1].setfailargs([v8, v2, v6, v5, v7, v1, v10]) looptoken = JitCellToken() - cpu.compile_loop(None, inputargs, operations, looptoken) + cpu.compile_loop(inputargs, operations, looptoken) args = [19 , -3 , -58 , -7 , 12 , 22 , -54 , -29 , -19 , -64] deadframe = cpu.execute_token(looptoken, *args) assert cpu.get_int_value(deadframe, 0) == -29 @@ -223,7 +223,7 @@ looptoken = JitCellToken() operations[5].setfailargs([]) operations[-1].setfailargs([v1, v4, v10, v8, v7, v3]) - cpu.compile_loop(None, inputargs, operations, looptoken) + cpu.compile_loop(inputargs, operations, looptoken) args = [1073741824 , 95 , -16 , 5 , 92 , 12 , 32 , 17 , 37 , -63] deadframe = cpu.execute_token(looptoken, *args) assert cpu.get_int_value(deadframe, 0) == 1073741824 @@ -280,7 +280,7 @@ 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(None, inputargs, operations, looptoken) + cpu.compile_loop(inputargs, operations, looptoken) deadframe = cpu.execute_token(looptoken, *args) assert cpu.get_latest_descr(deadframe).identifier == 3 assert cpu.get_int_value(deadframe, 0) == 12 @@ -328,7 +328,7 @@ operations[8].setfailargs([v5, v9]) operations[-1].setfailargs([v4, v10, v6, v5, v9, v7]) looptoken = JitCellToken() - cpu.compile_loop(None, inputargs, operations, looptoken) + cpu.compile_loop(inputargs, operations, looptoken) args = [-8 , 0 , 62 , 35 , 16 , 9 , 30 , 581610154 , -1 , 738197503] deadframe = cpu.execute_token(looptoken, *args) assert cpu.get_latest_descr(deadframe).identifier == 2 @@ -378,7 +378,7 @@ operations[-2].setfailargs([v9, v4, v10, v11, v14]) operations[-1].setfailargs([v10, v8, v1, v6, v4]) looptoken = JitCellToken() - cpu.compile_loop(None, inputargs, operations, looptoken) + cpu.compile_loop(inputargs, operations, looptoken) args = [-39 , -18 , 1588243114 , -9 , -4 , 1252698794 , 0 , 715827882 , -15 , 536870912] deadframe = cpu.execute_token(looptoken, *args) assert cpu.get_latest_descr(deadframe).identifier == 1 @@ -433,7 +433,7 @@ operations[9].setfailargs([v5, v7, v12, v14, v2, v13, v8]) operations[-1].setfailargs([v1, v2, v9]) looptoken = JitCellToken() - cpu.compile_loop(None, inputargs, operations, looptoken) + cpu.compile_loop(inputargs, operations, looptoken) args = [0 , -2 , 24 , 1 , -4 , 13 , -95 , 33 , 2 , -44] deadframe = cpu.execute_token(looptoken, *args) assert cpu.get_latest_descr(deadframe).identifier == 3 @@ -475,7 +475,7 @@ 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(None, inputargs, operations, looptoken) + cpu.compile_loop(inputargs, operations, looptoken) args = [3 , -5 , 1431655765 , 47 , 12 , 1789569706 , 15 , 939524096 , 16 , -43] deadframe = cpu.execute_token(looptoken, *args) assert cpu.get_latest_descr(deadframe).identifier == 1 @@ -524,7 +524,7 @@ operations[-1].setfailargs([v2, v3, v5, v7, v10, v8, v9]) operations[4].setfailargs([v14]) looptoken = JitCellToken() - cpu.compile_loop(None, inputargs, operations, looptoken) + cpu.compile_loop(inputargs, operations, looptoken) args = [14 , -20 , 18 , -2058005163 , 6 , 1 , -16 , 11 , 0 , 19] deadframe = cpu.execute_token(looptoken, *args) assert cpu.get_latest_descr(deadframe).identifier == 1 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 @@ -24,7 +24,7 @@ cpu = CPU(None, None) cpu.setup_once() looptoken = JitCellToken() - cpu.compile_loop(None, inputargs, operations, looptoken) + cpu.compile_loop(inputargs, operations, looptoken) deadframe = cpu.execute_token(looptoken, 9) assert cpu.get_int_value(deadframe, 0) == (9 >> 3) assert cpu.get_int_value(deadframe, 1) == (~18) @@ -48,7 +48,7 @@ cpu = CPU(None, None) cpu.setup_once() looptoken = JitCellToken() - cpu.compile_loop(None, inputargs, operations, looptoken) + cpu.compile_loop(inputargs, operations, looptoken) deadframe = cpu.execute_token(looptoken, -10) assert cpu.get_int_value(deadframe, 0) == 0 assert cpu.get_int_value(deadframe, 1) == -1000 @@ -145,7 +145,7 @@ cpu = CPU(None, None) cpu.setup_once() looptoken = JitCellToken() - cpu.compile_loop(None, inputargs, operations, looptoken) + cpu.compile_loop(inputargs, operations, looptoken) args = [-13 , 10 , 10 , 8 , -8 , -16 , -18 , 46 , -12 , 26] deadframe = cpu.execute_token(looptoken, *args) assert cpu.get_int_value(deadframe, 0) == 0 @@ -252,7 +252,7 @@ cpu = CPU(None, None) cpu.setup_once() looptoken = JitCellToken() - cpu.compile_loop(None, inputargs, operations, looptoken) + cpu.compile_loop(inputargs, operations, looptoken) args = [17 , -20 , -6 , 6 , 1 , 13 , 13 , 9 , 49 , 8] deadframe = cpu.execute_token(looptoken, *args) assert cpu.get_int_value(deadframe, 0) == 0 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 @@ -75,7 +75,7 @@ ResOperation(rop.FINISH, [inp[1]], None, descr=BasicFinalDescr(1)), ] operations[-2].setfailargs(out) - cpu.compile_loop(None, inp, operations, looptoken) + cpu.compile_loop(inp, operations, looptoken) args = [i for i in range(1, 15)] deadframe = self.cpu.execute_token(looptoken, *args) output = [self.cpu.get_int_value(deadframe, i - 1) for i in range(1, 15)] @@ -117,9 +117,9 @@ i1 = int_sub(i0, 1) finish(i1) ''') - self.cpu.compile_loop(None, loop2.inputargs, loop2.operations, lt2) - self.cpu.compile_loop(None, loop3.inputargs, loop3.operations, lt3) - self.cpu.compile_loop(None, loop1.inputargs, loop1.operations, lt1) + self.cpu.compile_loop(loop2.inputargs, loop2.operations, lt2) + self.cpu.compile_loop(loop3.inputargs, loop3.operations, lt3) + self.cpu.compile_loop(loop1.inputargs, loop1.operations, lt1) df = self.cpu.execute_token(lt1, 10) assert self.cpu.get_int_value(df, 0) == 7 @@ -214,7 +214,7 @@ ops = "".join(ops) loop = parse(ops) looptoken = JitCellToken() - self.cpu.compile_loop(None, loop.inputargs, loop.operations, looptoken) + self.cpu.compile_loop(loop.inputargs, loop.operations, looptoken) ARGS = [lltype.Signed] * numargs RES = lltype.Signed args = [i+1 for i in range(numargs)] @@ -246,7 +246,7 @@ try: self.cpu.assembler.set_debug(True) looptoken = JitCellToken() - self.cpu.compile_loop(None, ops.inputargs, ops.operations, looptoken) + self.cpu.compile_loop(ops.inputargs, ops.operations, looptoken) self.cpu.execute_token(looptoken, 0) # check debugging info struct = self.cpu.assembler.loop_run_counters[0] @@ -280,7 +280,7 @@ faildescr = BasicFailDescr(2) loop = parse(ops, self.cpu, namespace=locals()) looptoken = JitCellToken() - info = self.cpu.compile_loop(None, loop.inputargs, loop.operations, looptoken) + info = self.cpu.compile_loop(loop.inputargs, loop.operations, looptoken) ops2 = """ [i0, f1] i1 = same_as(i0) @@ -293,7 +293,7 @@ """ loop2 = parse(ops2, self.cpu, namespace=locals()) looptoken2 = JitCellToken() - info = self.cpu.compile_loop(None, loop2.inputargs, loop2.operations, looptoken2) + info = self.cpu.compile_loop(loop2.inputargs, loop2.operations, looptoken2) deadframe = self.cpu.execute_token(looptoken, -9, longlong.getfloatstorage(-13.5)) res = longlong.getrealfloat(self.cpu.get_float_value(deadframe, 0)) 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 @@ -183,8 +183,8 @@ self.stats = stats or MiniStats() self.vinfo_for_tests = kwds.get('vinfo_for_tests', None) - def compile_loop(self, logger, inputargs, operations, looptoken, log=True, - name=''): + def compile_loop(self, inputargs, operations, looptoken, log=True, + name='', logger=None): clt = model.CompiledLoopToken(self, looptoken.number) looptoken.compiled_loop_token = clt lltrace = LLTrace(inputargs, operations) @@ -192,8 +192,8 @@ clt._llgraph_alltraces = [lltrace] self._record_labels(lltrace) - def compile_bridge(self, logger, faildescr, inputargs, operations, - original_loop_token, log=True): + def compile_bridge(self, faildescr, inputargs, operations, + original_loop_token, log=True, logger=None): clt = original_loop_token.compiled_loop_token clt.compiling_a_bridge() lltrace = LLTrace(inputargs, operations) 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 @@ -68,14 +68,32 @@ function(arg, node.val) node = node.next - def pop(self, size, tp): + def pop(self, size, tp, hint=-1): if size == 2: - return self._pop_two(tp) + return self._pop_two(tp) # 'hint' ignored for floats on 32-bit assert size == 1 if not self.master_node: return None node = self.master_node - self.master_node = node.next + # + if hint >= 0: + # Look for and remove the Node with the .val matching 'hint'. + # If not found, fall back to removing the first Node. + # Note that the loop below ignores the first Node, but + # even if by chance it is the one with the correct .val, + # it will be the one we remove at the end anyway. + prev_node = node + while prev_node.next: + if prev_node.next.val == hint: + node = prev_node.next + prev_node.next = node.next + break + prev_node = prev_node.next + else: + self.master_node = node.next + else: + self.master_node = node.next + # return self.fm.frame_pos(node.val, tp) def _candidate(self, node): @@ -131,8 +149,7 @@ def __init__(self, start_free_depth=0, freelist=None): self.bindings = {} self.current_frame_depth = start_free_depth - # we disable hints for now - #self.hint_frame_locations = {} + self.hint_frame_pos = {} self.freelist = LinkedList(self, freelist) def get_frame_depth(self): @@ -148,22 +165,16 @@ return self.bindings[box] except KeyError: pass - # check if we have a hint for this box - #if box in self.hint_frame_locations: - # # if we do, try to reuse the location for this box - # loc = self.hint_frame_locations[box] - # if self.try_to_reuse_location(box, loc): - # return loc - ## no valid hint. make up a new free location return self.get_new_loc(box) def get_new_loc(self, box): size = self.frame_size(box.type) + hint = self.hint_frame_pos.get(box, -1) # frame_depth is rounded up to a multiple of 'size', assuming # that 'size' is a power of two. The reason for doing so is to # avoid obscure issues in jump.py with stack locations that try # to move from position (6,7) to position (7,8). - newloc = self.freelist.pop(size, box.type) + newloc = self.freelist.pop(size, box.type, hint) if newloc is None: # index = self.get_frame_depth() @@ -232,23 +243,6 @@ all[node.val] = 1 node = node.next - def try_to_reuse_location(self, box, loc): - xxx - index = self.get_loc_index(loc) - if index < 0: - return False - size = self.frame_size(box.type) - for i in range(size): - while (index + i) >= len(self.used): - self.used.append(False) - if self.used[index + i]: - return False # already in use - # good, we can reuse the location - for i in range(size): - self.used[index + i] = True - self.bindings[box] = loc - return True - @staticmethod def _gather_gcroots(lst, var): lst.append(var) 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 @@ -676,7 +676,7 @@ 'checkdescr': checkdescr, 'fielddescr': cpu.fielddescrof(S, 'x')}) token = JitCellToken() - cpu.compile_loop(None, loop.inputargs, loop.operations, token) + cpu.compile_loop(loop.inputargs, loop.operations, token) p0 = lltype.malloc(S, zero=True) p1 = lltype.malloc(S) p2 = lltype.malloc(S) @@ -715,7 +715,7 @@ 'calldescr': checkdescr, }) token = JitCellToken() - cpu.compile_loop(None, loop.inputargs, loop.operations, token) + cpu.compile_loop(loop.inputargs, loop.operations, token) S = self.S s = lltype.malloc(S) cpu.execute_token(token, 1, s) @@ -743,7 +743,7 @@ token = JitCellToken() cpu.gc_ll_descr.init_nursery(20) cpu.setup_once() - cpu.compile_loop(None, loop.inputargs, loop.operations, token) + cpu.compile_loop(loop.inputargs, loop.operations, token) arg = longlong.getfloatstorage(2.3) frame = cpu.execute_token(token, arg) ofs = cpu.get_baseofs_of_frame_field() @@ -770,7 +770,7 @@ cpu.gc_ll_descr.collections = [[0, sizeof.size]] cpu.gc_ll_descr.init_nursery(2 * sizeof.size) cpu.setup_once() - cpu.compile_loop(None, loop.inputargs, loop.operations, token) + cpu.compile_loop(loop.inputargs, loop.operations, token) frame = cpu.execute_token(token) # now we should be able to track everything from the frame frame = lltype.cast_opaque_ptr(JITFRAMEPTR, frame) @@ -821,7 +821,7 @@ token = JitCellToken() cpu.gc_ll_descr.init_nursery(100) cpu.setup_once() - cpu.compile_loop(None, loop.inputargs, loop.operations, token) + cpu.compile_loop(loop.inputargs, loop.operations, token) args = [lltype.nullptr(llmemory.GCREF.TO) for i in range(7)] frame = cpu.execute_token(token, 1, *args) frame = rffi.cast(JITFRAMEPTR, frame) @@ -867,7 +867,7 @@ token = JitCellToken() cpu.gc_ll_descr.init_nursery(100) cpu.setup_once() - cpu.compile_loop(None, loop.inputargs, loop.operations, token) + cpu.compile_loop(loop.inputargs, loop.operations, token) frame = lltype.cast_opaque_ptr(JITFRAMEPTR, cpu.execute_token(token, 1, a)) @@ -911,7 +911,7 @@ token = JitCellToken() cpu.gc_ll_descr.init_nursery(100) cpu.setup_once() - cpu.compile_loop(None, loop.inputargs, loop.operations, token) + cpu.compile_loop(loop.inputargs, loop.operations, token) frame = lltype.cast_opaque_ptr(JITFRAMEPTR, cpu.execute_token(token, 1, a)) assert getmap(frame).count('1') == 4 diff --git a/rpython/jit/backend/llsupport/test/test_regalloc.py b/rpython/jit/backend/llsupport/test/test_regalloc.py --- a/rpython/jit/backend/llsupport/test/test_regalloc.py +++ b/rpython/jit/backend/llsupport/test/test_regalloc.py @@ -379,48 +379,23 @@ def test_hint_frame_locations_1(self): - py.test.skip("xxx") - b0, = newboxes(0) - fm = TFrameManager() - loc123 = FakeFramePos(123, INT) - fm.hint_frame_locations[b0] = loc123 - assert fm.get_frame_depth() == 0 - loc = fm.loc(b0) - assert loc == loc123 - assert fm.get_frame_depth() == 124 - - def test_hint_frame_locations_2(self): - py.test.skip("xxx") - b0, b1, b2 = newboxes(0, 1, 2) - longevity = {b0: (0, 1), b1: (0, 2), b2: (0, 2)} - fm = TFrameManager() - asm = MockAsm() - rm = RegisterManager(longevity, frame_manager=fm, assembler=asm) - rm.force_allocate_reg(b0) - rm.force_allocate_reg(b1) - rm.force_allocate_reg(b2) - rm.force_spill_var(b0) - loc = rm.loc(b0) - assert isinstance(loc, FakeFramePos) - assert fm.get_loc_index(loc) == 0 - rm.position = 1 - assert fm.used == [True] - rm.possibly_free_var(b0) - assert fm.used == [False] - # - fm.hint_frame_locations[b1] = loc - rm.force_spill_var(b1) - loc1 = rm.loc(b1) - assert loc1 == loc - assert fm.used == [True] - # - fm.hint_frame_locations[b2] = loc - rm.force_spill_var(b2) - loc2 = rm.loc(b2) - assert loc2 != loc1 # because it was not free - assert fm.used == [True, True] - # - rm._check_invariants() + for hint_value in range(11): + b0, = newboxes(0) + fm = TFrameManager() + fm.hint_frame_pos[b0] = hint_value + blist = newboxes(*range(10)) + for b1 in blist: + fm.loc(b1) + for b1 in blist: + fm.mark_as_free(b1) + assert fm.get_frame_depth() == 10 + loc = fm.loc(b0) + if hint_value < 10: + expected = hint_value + else: + expected = 0 + assert fm.get_loc_index(loc) == expected + assert fm.get_frame_depth() == 10 def test_linkedlist(self): class Loc(object): 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 @@ -97,7 +97,7 @@ loop = self.parse(ops, namespace=namespace) self.loop = loop looptoken = JitCellToken() - self.cpu.compile_loop(None, loop.inputargs, loop.operations, looptoken) + self.cpu.compile_loop(loop.inputargs, loop.operations, looptoken) arguments = [] for arg in args: if isinstance(arg, int): @@ -147,7 +147,7 @@ assert ([box.type for box in bridge.inputargs] == [box.type for box in guard_op.getfailargs()]) faildescr = guard_op.getdescr() - self.cpu.compile_bridge(None, faildescr, bridge.inputargs, + self.cpu.compile_bridge(faildescr, bridge.inputargs, bridge.operations, loop._jitcelltoken) return bridge diff --git a/rpython/jit/backend/llsupport/test/test_runner.py b/rpython/jit/backend/llsupport/test/test_runner.py --- a/rpython/jit/backend/llsupport/test/test_runner.py +++ b/rpython/jit/backend/llsupport/test/test_runner.py @@ -14,7 +14,7 @@ def set_debug(flag): pass - def compile_loop(self, logger, inputargs, operations, looptoken): + def compile_loop(self, inputargs, operations, looptoken): py.test.skip("llsupport test: cannot compile operations") 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 @@ -51,30 +51,21 @@ """ return False - def compile_loop(self, logger, inputargs, operations, looptoken, - log=True, name=''): + def compile_loop(self, inputargs, operations, looptoken, + log=True, name='', logger=None): """Assemble the given loop. Should create and attach a fresh CompiledLoopToken to looptoken.compiled_loop_token and stick extra attributes on it to point to the compiled loop in assembler. - - Optionally, return a ``ops_offset`` dictionary, which maps each operation - to its offset in the compiled code. The ``ops_offset`` dictionary is then - used by the operation logger to print the offsets in the log. The - offset representing the end of the last operation is stored in - ``ops_offset[None]``: note that this might not coincide with the end of - the loop, because usually in the loop footer there is code which does - not belong to any particular operation. + Returns either None or an instance of rpython.rlib.jit.AsmInfo. """ raise NotImplementedError - def compile_bridge(self, logger, faildescr, inputargs, operations, - original_loop_token, log=True): + def compile_bridge(self, faildescr, inputargs, operations, + original_loop_token, log=True, logger=None): """Assemble the bridge. The FailDescr is the descr of the original guard that failed. - - Optionally, return a ``ops_offset`` dictionary. See the docstring of - ``compiled_loop`` for more information about it. + Returns either None or an instance of rpython.rlib.jit.AsmInfo. """ raise NotImplementedError 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 @@ -105,7 +105,7 @@ loop = parse(ops, namespace=locals()) looptoken = JitCellToken() - self.cpu.compile_loop(None, loop.inputargs, loop.operations, looptoken) + self.cpu.compile_loop(loop.inputargs, loop.operations, looptoken) argvals, expected_result = self._prepare_args(args, floats, ints) deadframe = self.cpu.execute_token(looptoken, *argvals) @@ -249,7 +249,7 @@ called_looptoken = JitCellToken() called_looptoken.outermost_jitdriver_sd = FakeJitDriverSD() done_descr = called_loop.operations[-1].getdescr() - self.cpu.compile_loop(None, called_loop.inputargs, called_loop.operations, called_looptoken) + self.cpu.compile_loop(called_loop.inputargs, called_loop.operations, called_looptoken) argvals, expected_result = self._prepare_args(args, floats, ints) deadframe = cpu.execute_token(called_looptoken, *argvals) @@ -278,7 +278,7 @@ self.cpu.done_with_this_frame_descr_float = done_descr try: othertoken = JitCellToken() - self.cpu.compile_loop(None, loop.inputargs, loop.operations, othertoken) + self.cpu.compile_loop(loop.inputargs, loop.operations, othertoken) # prepare call to called_loop argvals, _ = self._prepare_args(args, floats, ints) @@ -424,7 +424,7 @@ loop = parse(ops, namespace=locals()) looptoken = JitCellToken() - self.cpu.compile_loop(None, loop.inputargs, loop.operations, looptoken) + self.cpu.compile_loop(loop.inputargs, loop.operations, looptoken) argvals, expected_result = self._prepare_args(args, floats, ints) deadframe = self.cpu.execute_token(looptoken, *argvals) 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 @@ -49,7 +49,7 @@ valueboxes, descr) looptoken = JitCellToken() - self.cpu.compile_loop(None, inputargs, operations, looptoken) + self.cpu.compile_loop(inputargs, operations, looptoken) args = [] for box in inputargs: if isinstance(box, BoxInt): @@ -127,7 +127,7 @@ ] inputargs = [i0] looptoken = JitCellToken() - self.cpu.compile_loop(None, inputargs, operations, looptoken) + self.cpu.compile_loop(inputargs, operations, looptoken) deadframe = self.cpu.execute_token(looptoken, 2) fail = self.cpu.get_latest_descr(deadframe) res = self.cpu.get_int_value(deadframe, 0) @@ -145,7 +145,7 @@ ] inputargs = [i0] looptoken = JitCellToken() - self.cpu.compile_loop(None, inputargs, operations, looptoken) + self.cpu.compile_loop(inputargs, operations, looptoken) deadframe = self.cpu.execute_token(looptoken, longlong.getfloatstorage(2.8)) fail = self.cpu.get_latest_descr(deadframe) @@ -170,7 +170,7 @@ inputargs = [i0] operations[3].setfailargs([i1]) - self.cpu.compile_loop(None, inputargs, operations, looptoken) + self.cpu.compile_loop(inputargs, operations, looptoken) deadframe = self.cpu.execute_token(looptoken, 2) fail = self.cpu.get_latest_descr(deadframe) assert fail.identifier == 2 @@ -195,7 +195,7 @@ inputargs = [i3] operations[4].setfailargs([None, None, i1, None]) - self.cpu.compile_loop(None, inputargs, operations, looptoken) + self.cpu.compile_loop(inputargs, operations, looptoken) deadframe = self.cpu.execute_token(looptoken, 44) fail = self.cpu.get_latest_descr(deadframe) assert fail.identifier == 2 @@ -221,7 +221,7 @@ operations[3].setfailargs([i1]) wr_i1 = weakref.ref(i1) wr_guard = weakref.ref(operations[2]) - self.cpu.compile_loop(None, inputargs, operations, looptoken) + self.cpu.compile_loop(inputargs, operations, looptoken) if hasattr(looptoken, '_x86_ops_offset'): del looptoken._x86_ops_offset # else it's kept alive del i0, i1, i2 @@ -249,7 +249,7 @@ ] inputargs = [i0] operations[3].setfailargs([i1]) - self.cpu.compile_loop(None, inputargs, operations, looptoken) + self.cpu.compile_loop(inputargs, operations, looptoken) i1b = BoxInt() i3 = BoxInt() @@ -260,7 +260,7 @@ ] bridge[1].setfailargs([i1b]) - self.cpu.compile_bridge(None, faildescr1, [i1b], bridge, looptoken) + self.cpu.compile_bridge(faildescr1, [i1b], bridge, looptoken) deadframe = self.cpu.execute_token(looptoken, 2) fail = self.cpu.get_latest_descr(deadframe) @@ -291,7 +291,7 @@ ] inputargs = [i3] operations[4].setfailargs([None, i1, None]) - self.cpu.compile_loop(None, inputargs, operations, looptoken) + self.cpu.compile_loop(inputargs, operations, looptoken) i1b = BoxInt() i3 = BoxInt() @@ -302,7 +302,7 @@ ] bridge[1].setfailargs([i1b]) - self.cpu.compile_bridge(None, faildescr1, [i1b], bridge, looptoken) + self.cpu.compile_bridge(faildescr1, [i1b], bridge, looptoken) deadframe = self.cpu.execute_token(looptoken, 2) fail = self.cpu.get_latest_descr(deadframe) @@ -320,7 +320,7 @@ ] inputargs = [i0] operations[0].setfailargs([i0]) - self.cpu.compile_loop(None, inputargs, operations, looptoken) + self.cpu.compile_loop(inputargs, operations, looptoken) i1list = [BoxInt() for i in range(150)] bridge = [] @@ -334,7 +334,7 @@ descr=BasicFinalDescr(4))) bridge[-2].setfailargs(i1list) - self.cpu.compile_bridge(None, faildescr1, [i0], bridge, looptoken) + self.cpu.compile_bridge(faildescr1, [i0], bridge, looptoken) deadframe = self.cpu.execute_token(looptoken, 1) fail = self.cpu.get_latest_descr(deadframe) @@ -358,7 +358,7 @@ operations = [ ResOperation(rop.FINISH, [i0], None, descr=faildescr) ] - self.cpu.compile_loop(None, [i0], operations, looptoken) + self.cpu.compile_loop([i0], operations, looptoken) deadframe = self.cpu.execute_token(looptoken, 99) fail = self.cpu.get_latest_descr(deadframe) assert fail is faildescr @@ -369,7 +369,7 @@ operations = [ ResOperation(rop.FINISH, [ConstInt(42)], None, descr=faildescr) ] - self.cpu.compile_loop(None, [], operations, looptoken) + self.cpu.compile_loop([], operations, looptoken) deadframe = self.cpu.execute_token(looptoken) fail = self.cpu.get_latest_descr(deadframe) assert fail is faildescr @@ -380,7 +380,7 @@ operations = [ ResOperation(rop.FINISH, [], None, descr=faildescr) ] - self.cpu.compile_loop(None, [], operations, looptoken) + self.cpu.compile_loop([], operations, looptoken) deadframe = self.cpu.execute_token(looptoken) fail = self.cpu.get_latest_descr(deadframe) assert fail is faildescr @@ -391,7 +391,7 @@ operations = [ ResOperation(rop.FINISH, [f0], None, descr=faildescr) ] - self.cpu.compile_loop(None, [f0], operations, looptoken) + self.cpu.compile_loop([f0], operations, looptoken) value = longlong.getfloatstorage(-61.25) deadframe = self.cpu.execute_token(looptoken, value) fail = self.cpu.get_latest_descr(deadframe) @@ -403,7 +403,7 @@ operations = [ ResOperation(rop.FINISH, [constfloat(42.5)], None, descr=faildescr) ] - self.cpu.compile_loop(None, [], operations, looptoken) + self.cpu.compile_loop([], operations, looptoken) deadframe = self.cpu.execute_token(looptoken) fail = self.cpu.get_latest_descr(deadframe) assert fail is faildescr @@ -429,7 +429,7 @@ ResOperation(rop.JUMP, [t, z], None, descr=targettoken), ] operations[-2].setfailargs([t, z]) - cpu.compile_loop(None, [x, y], operations, looptoken) + cpu.compile_loop([x, y], operations, looptoken) deadframe = self.cpu.execute_token(looptoken, 0, 10) assert self.cpu.get_int_value(deadframe, 0) == 0 assert self.cpu.get_int_value(deadframe, 1) == 55 @@ -488,7 +488,7 @@ ops[1].setfailargs([v_res]) # looptoken = JitCellToken() - self.cpu.compile_loop(None, [v1, v2], ops, looptoken) + self.cpu.compile_loop([v1, v2], ops, looptoken) for x, y, z in testcases: deadframe = self.cpu.execute_token(looptoken, x, y) fail = self.cpu.get_latest_descr(deadframe) @@ -1238,7 +1238,7 @@ print inputargs for op in operations: print op - self.cpu.compile_loop(None, inputargs, operations, looptoken) + self.cpu.compile_loop(inputargs, operations, looptoken) # deadframe = self.cpu.execute_token(looptoken, *values) fail = self.cpu.get_latest_descr(deadframe) @@ -1305,7 +1305,7 @@ operations[3].setfailargs(inputargs[:]) operations[3].setdescr(faildescr) # - self.cpu.compile_loop(None, inputargs, operations, looptoken) + self.cpu.compile_loop(inputargs, operations, looptoken) # values = [] S = lltype.GcStruct('S') @@ -1366,7 +1366,7 @@ operations[-3].setfailargs(fboxes) operations[-2].setfailargs(fboxes) looptoken = JitCellToken() - self.cpu.compile_loop(None, fboxes, operations, looptoken) + self.cpu.compile_loop(fboxes, operations, looptoken) fboxes2 = [BoxFloat() for i in range(12)] f3 = BoxFloat() @@ -1375,7 +1375,7 @@ ResOperation(rop.JUMP, [f3]+fboxes2[1:], None, descr=targettoken), ] - self.cpu.compile_bridge(None, faildescr1, fboxes2, bridge, looptoken) + self.cpu.compile_bridge(faildescr1, fboxes2, bridge, looptoken) args = [] for i in range(len(fboxes)): @@ -1407,7 +1407,7 @@ finish()""" loop = parse(loopops) looptoken = JitCellToken() - self.cpu.compile_loop(None, loop.inputargs, loop.operations, looptoken) + self.cpu.compile_loop(loop.inputargs, loop.operations, looptoken) args = [1] args.append(longlong.getfloatstorage(132.25)) args.append(longlong.getfloatstorage(0.75)) @@ -1428,7 +1428,7 @@ ResOperation(rop.FINISH, [], None, descr=faildescr2), ] bridgeops[-2].setfailargs(fboxes[:]) - self.cpu.compile_bridge(None, loop.operations[-2].getdescr(), fboxes, + self.cpu.compile_bridge(loop.operations[-2].getdescr(), fboxes, bridgeops, looptoken) args = [1, longlong.getfloatstorage(132.25), @@ -1463,7 +1463,7 @@ ] operations[1].setfailargs([]) looptoken = JitCellToken() - self.cpu.compile_loop(None, inputargs, operations, looptoken) + self.cpu.compile_loop(inputargs, operations, looptoken) # for value in [-42, 0, 1, 10]: deadframe = self.cpu.execute_token(looptoken, value) @@ -1508,7 +1508,7 @@ ] operations[-2].setfailargs([]) looptoken = JitCellToken() - self.cpu.compile_loop(None, inputargs, operations, looptoken) + self.cpu.compile_loop(inputargs, operations, looptoken) # for test1 in [-65, -42, -11, 0, 1, 10]: if test1 == -42 or combinaison[0] == 'b': @@ -1560,7 +1560,7 @@ ] operations[-2].setfailargs([]) looptoken = JitCellToken() - self.cpu.compile_loop(None, inputargs, operations, looptoken) + self.cpu.compile_loop(inputargs, operations, looptoken) # for test1 in [65, 42, 11, 0, 1]: if test1 == 42 or combinaison[0] == 'b': @@ -1616,7 +1616,7 @@ ] operations[-2].setfailargs([]) looptoken = JitCellToken() - self.cpu.compile_loop(None, inputargs, operations, looptoken) + self.cpu.compile_loop(inputargs, operations, looptoken) # nan = 1e200 * 1e200 nan /= nan @@ -1675,7 +1675,7 @@ descr=faildescr)) looptoken = JitCellToken() # - self.cpu.compile_loop(None, inputargs, operations, looptoken) + self.cpu.compile_loop(inputargs, operations, looptoken) # args = [] for box in inputargs: @@ -1748,7 +1748,7 @@ looptoken = JitCellToken() # Use "set" to unique-ify inputargs unique_testcase_list = list(set(testcase)) - self.cpu.compile_loop(None, unique_testcase_list, operations, + self.cpu.compile_loop(unique_testcase_list, operations, looptoken) args = [box.getfloatstorage() for box in unique_testcase_list] @@ -2065,7 +2065,7 @@ exc_ptr = xptr loop = parse(ops, self.cpu, namespace=locals()) looptoken = JitCellToken() - self.cpu.compile_loop(None, loop.inputargs, loop.operations, looptoken) + self.cpu.compile_loop(loop.inputargs, loop.operations, looptoken) deadframe = self.cpu.execute_token(looptoken, 1) assert self.cpu.get_ref_value(deadframe, 0) == xptr excvalue = self.cpu.grab_exc_value(deadframe) @@ -2088,7 +2088,7 @@ exc_ptr = yptr loop = parse(ops, self.cpu, namespace=locals()) looptoken = JitCellToken() - self.cpu.compile_loop(None, loop.inputargs, loop.operations, looptoken) + self.cpu.compile_loop(loop.inputargs, loop.operations, looptoken) deadframe = self.cpu.execute_token(looptoken, 1) assert self.cpu.get_int_value(deadframe, 0) == 1 excvalue = self.cpu.grab_exc_value(deadframe) @@ -2105,7 +2105,7 @@ ''' loop = parse(ops, self.cpu, namespace=locals()) looptoken = JitCellToken() - self.cpu.compile_loop(None, loop.inputargs, loop.operations, looptoken) + self.cpu.compile_loop(loop.inputargs, loop.operations, looptoken) deadframe = self.cpu.execute_token(looptoken, 1) assert self.cpu.get_int_value(deadframe, 0) == 1 excvalue = self.cpu.grab_exc_value(deadframe) @@ -2284,7 +2284,7 @@ 'func_ptr': func_ptr, 'calldescr': calldescr}) looptoken = JitCellToken() - self.cpu.compile_loop(None, loop.inputargs, loop.operations, looptoken) + self.cpu.compile_loop(loop.inputargs, loop.operations, looptoken) f1 = longlong.getfloatstorage(1.2) f2 = longlong.getfloatstorage(3.4) frame = self.cpu.execute_token(looptoken, 1, 0, 1, 2, 3, 4, 5, f1, f2) @@ -2329,7 +2329,7 @@ ] ops[2].setfailargs([i1, i0]) looptoken = JitCellToken() - self.cpu.compile_loop(None, [i0, i1], ops, looptoken) + self.cpu.compile_loop([i0, i1], ops, looptoken) deadframe = self.cpu.execute_token(looptoken, 20, 0) fail = self.cpu.get_latest_descr(deadframe) assert fail.identifier == 0 @@ -2375,7 +2375,7 @@ ] ops[2].setfailargs([i1, i2, i0]) looptoken = JitCellToken() - self.cpu.compile_loop(None, [i0, i1], ops, looptoken) + self.cpu.compile_loop([i0, i1], ops, looptoken) deadframe = self.cpu.execute_token(looptoken, 20, 0) fail = self.cpu.get_latest_descr(deadframe) assert fail.identifier == 0 @@ -2423,7 +2423,7 @@ ] ops[2].setfailargs([i1, f2, i0]) looptoken = JitCellToken() - self.cpu.compile_loop(None, [i0, i1], ops, looptoken) + self.cpu.compile_loop([i0, i1], ops, looptoken) deadframe = self.cpu.execute_token(looptoken, 20, 0) fail = self.cpu.get_latest_descr(deadframe) assert fail.identifier == 0 @@ -2465,7 +2465,7 @@ ] ops[1].setfailargs([i1, i2]) looptoken = JitCellToken() - self.cpu.compile_loop(None, [i1], ops, looptoken) + self.cpu.compile_loop([i1], ops, looptoken) deadframe = self.cpu.execute_token(looptoken, ord('G')) fail = self.cpu.get_latest_descr(deadframe) assert fail.identifier == 0 @@ -2523,7 +2523,7 @@ ] ops[1].setfailargs([]) looptoken = JitCellToken() - self.cpu.compile_loop(None, [i0, i1, i2, i3], ops, looptoken) + self.cpu.compile_loop([i0, i1, i2, i3], ops, looptoken) args = [rffi.cast(lltype.Signed, raw), 2, 4, @@ -2580,7 +2580,7 @@ ResOperation(rop.FINISH, [i3], None, descr=BasicFinalDescr(0)) ] looptoken = JitCellToken() - self.cpu.compile_loop(None, [i1, i2], ops, looptoken) + self.cpu.compile_loop([i1, i2], ops, looptoken) buffer = lltype.malloc(rffi.CCHARP.TO, buflen, flavor='raw') args = [buflen, rffi.cast(lltype.Signed, buffer)] @@ -2650,7 +2650,7 @@ ] ops[1].setfailargs([]) looptoken = JitCellToken() - self.cpu.compile_loop(None, [], ops, looptoken) + self.cpu.compile_loop([], ops, looptoken) deadframe = self.cpu.execute_token(looptoken) fail = self.cpu.get_latest_descr(deadframe) @@ -2790,7 +2790,7 @@ ops.insert(-1, ResOperation(rop.SAME_AS, [b1], b1.clonebox())) looptoken = JitCellToken() - self.cpu.compile_loop(None, argboxes, ops, looptoken) + self.cpu.compile_loop(argboxes, ops, looptoken) # seen = [] deadframe = self.cpu.execute_token(looptoken, *argvalues_normal) @@ -2815,7 +2815,7 @@ ] ops[0].setfailargs([i1]) looptoken = JitCellToken() - self.cpu.compile_loop(None, [i0, i1], ops, looptoken) + self.cpu.compile_loop([i0, i1], ops, looptoken) deadframe = self.cpu.execute_token(looptoken, -42, 9) fail = self.cpu.get_latest_descr(deadframe) @@ -2842,7 +2842,7 @@ ResOperation(rop.FINISH, [i2], None, descr=BasicFinalDescr(3)) ] ops[0].setfailargs([]) - self.cpu.compile_bridge(None, faildescr, [i2], ops, looptoken) + self.cpu.compile_bridge(faildescr, [i2], ops, looptoken) deadframe = self.cpu.execute_token(looptoken, -42, 9) fail = self.cpu.get_latest_descr(deadframe) @@ -2875,7 +2875,7 @@ ] ops[0].setfailargs([]) looptoken = JitCellToken() - self.cpu.compile_loop(None, [i0], ops, looptoken) + self.cpu.compile_loop([i0], ops, looptoken) # mark as failing self.cpu.invalidate_loop(looptoken) # attach a bridge @@ -2883,7 +2883,7 @@ ops2 = [ ResOperation(rop.JUMP, [ConstInt(333)], None, descr=labeldescr), ] - self.cpu.compile_bridge(None, faildescr, [], ops2, looptoken) + self.cpu.compile_bridge(faildescr, [], ops2, looptoken) # run: must not be caught in an infinite loop deadframe = self.cpu.execute_token(looptoken, 16) fail = self.cpu.get_latest_descr(deadframe) @@ -3091,7 +3091,7 @@ looptoken.outermost_jitdriver_sd = FakeJitDriverSD() finish_descr = loop.operations[-1].getdescr() self.cpu.done_with_this_frame_descr_int = BasicFinalDescr() - self.cpu.compile_loop(None, loop.inputargs, loop.operations, looptoken) + self.cpu.compile_loop(loop.inputargs, loop.operations, looptoken) ARGS = [lltype.Signed] * 10 RES = lltype.Signed FakeJitDriverSD.portal_calldescr = self.cpu.calldescrof( @@ -3109,7 +3109,7 @@ ''' loop = parse(ops, namespace=locals()) othertoken = JitCellToken() - self.cpu.compile_loop(None, loop.inputargs, loop.operations, othertoken) + self.cpu.compile_loop(loop.inputargs, loop.operations, othertoken) args = [i+1 for i in range(10)] deadframe = self.cpu.execute_token(othertoken, *args) assert self.cpu.get_int_value(deadframe, 0) == 13 @@ -3119,7 +3119,7 @@ del called[:] self.cpu.done_with_this_frame_descr_int = finish_descr othertoken = JitCellToken() - self.cpu.compile_loop(None, loop.inputargs, loop.operations, othertoken) + self.cpu.compile_loop(loop.inputargs, loop.operations, othertoken) args = [i+1 for i in range(10)] deadframe = self.cpu.execute_token(othertoken, *args) assert self.cpu.get_int_value(deadframe, 0) == 97 @@ -3157,7 +3157,7 @@ loop = parse(ops) looptoken = JitCellToken() looptoken.outermost_jitdriver_sd = FakeJitDriverSD() - self.cpu.compile_loop(None, loop.inputargs, loop.operations, looptoken) + self.cpu.compile_loop(loop.inputargs, loop.operations, looptoken) ARGS = [lltype.Signed] * 10 RES = lltype.Signed FakeJitDriverSD.portal_calldescr = self.cpu.calldescrof( @@ -3171,7 +3171,7 @@ ''' loop = parse(ops, namespace=locals()) othertoken = JitCellToken() - self.cpu.compile_loop(None, loop.inputargs, loop.operations, othertoken) + self.cpu.compile_loop(loop.inputargs, loop.operations, othertoken) deadframe = self.cpu.execute_token(othertoken, sys.maxint - 1) assert self.cpu.get_int_value(deadframe, 0) == 3 @@ -3209,7 +3209,7 @@ looptoken = JitCellToken() looptoken.outermost_jitdriver_sd = FakeJitDriverSD() self.cpu.done_with_this_frame_descr_float = BasicFinalDescr() - self.cpu.compile_loop(None, loop.inputargs, loop.operations, looptoken) + self.cpu.compile_loop(loop.inputargs, loop.operations, looptoken) args = [longlong.getfloatstorage(1.2), longlong.getfloatstorage(2.3)] deadframe = self.cpu.execute_token(looptoken, *args) @@ -3223,7 +3223,7 @@ ''' loop = parse(ops, namespace=locals()) othertoken = JitCellToken() - self.cpu.compile_loop(None, loop.inputargs, loop.operations, othertoken) + self.cpu.compile_loop(loop.inputargs, loop.operations, othertoken) args = [longlong.getfloatstorage(1.2), longlong.getfloatstorage(3.2)] deadframe = self.cpu.execute_token(othertoken, *args) @@ -3235,7 +3235,7 @@ del called[:] self.cpu.done_with_this_frame_descr_float = finish_descr othertoken = JitCellToken() - self.cpu.compile_loop(None, loop.inputargs, loop.operations, othertoken) + self.cpu.compile_loop(loop.inputargs, loop.operations, othertoken) args = [longlong.getfloatstorage(1.2), longlong.getfloatstorage(4.2)] deadframe = self.cpu.execute_token(othertoken, *args) @@ -3298,7 +3298,7 @@ looptoken = JitCellToken() looptoken.outermost_jitdriver_sd = FakeJitDriverSD() self.cpu.done_with_this_frame_descr_float = BasicFinalDescr() - self.cpu.compile_loop(None, loop.inputargs, loop.operations, looptoken) + self.cpu.compile_loop(loop.inputargs, loop.operations, looptoken) finish_descr = loop.operations[-1].getdescr() args = [longlong.getfloatstorage(1.25), longlong.getfloatstorage(2.35)] @@ -3315,7 +3315,7 @@ ''' loop = parse(ops, namespace=locals()) othertoken = JitCellToken() - self.cpu.compile_loop(None, loop.inputargs, loop.operations, othertoken) + self.cpu.compile_loop(loop.inputargs, loop.operations, othertoken) # normal call_assembler: goes to looptoken args = [longlong.getfloatstorage(1.25), @@ -3334,7 +3334,7 @@ loop2 = parse(ops) looptoken2 = JitCellToken() looptoken2.outermost_jitdriver_sd = FakeJitDriverSD() - self.cpu.compile_loop(None, loop2.inputargs, loop2.operations, looptoken2) + self.cpu.compile_loop(loop2.inputargs, loop2.operations, looptoken2) finish_descr2 = loop2.operations[-1].getdescr() # install it @@ -3694,7 +3694,7 @@ ] inputargs = [i0] looptoken = JitCellToken() - self.cpu.compile_loop(None, inputargs, operations, looptoken) + self.cpu.compile_loop(inputargs, operations, looptoken) # overflowing value: deadframe = self.cpu.execute_token(looptoken, sys.maxint // 4 + 1) fail = self.cpu.get_latest_descr(deadframe) @@ -3747,7 +3747,7 @@ operations[3].setfailargs([i1]) operations[6].setfailargs([i1]) From noreply at buildbot.pypy.org Tue Sep 17 02:28:15 2013 From: noreply at buildbot.pypy.org (pjenvey) Date: Tue, 17 Sep 2013 02:28:15 +0200 (CEST) Subject: [pypy-commit] pypy py3k: bring over the issue #1595 fix from default Message-ID: <20130917002815.F1BFE1C0842@cobra.cs.uni-duesseldorf.de> Author: Philip Jenvey Branch: py3k Changeset: r66986:e2d622c67269 Date: 2013-09-16 17:27 -0700 http://bitbucket.org/pypy/pypy/changeset/e2d622c67269/ Log: bring over the issue #1595 fix from default diff --git a/lib-python/3/argparse.py b/lib-python/3/argparse.py --- a/lib-python/3/argparse.py +++ b/lib-python/3/argparse.py @@ -1789,7 +1789,19 @@ # error if this argument is not allowed with other previously # seen arguments, assuming that actions that use the default # value don't really count as "present" - if argument_values is not action.default: + + # XXX PyPy bug-to-bug compatibility: "is" on primitive types + # is not consistent in CPython. We'll assume it is close + # enough for ints (which is true only for "small ints"), but + # for floats and longs and complexes we'll go for the option + # of forcing "is" to say False, like it usually does on + # CPython. A fix is pending on CPython trunk + # (http://bugs.python.org/issue18943) but that might change + # the details of the semantics and so not be applied to 2.7. + # See the line AA below. + + if (argument_values is not action.default or + type(argument_values) in (float, int, complex)): # AA seen_non_default_actions.add(action) for conflict_action in action_conflicts.get(action, []): if conflict_action in seen_non_default_actions: From noreply at buildbot.pypy.org Tue Sep 17 08:44:03 2013 From: noreply at buildbot.pypy.org (mattip) Date: Tue, 17 Sep 2013 08:44:03 +0200 (CEST) Subject: [pypy-commit] pypy default: typo Message-ID: <20130917064403.DE92E1C0113@cobra.cs.uni-duesseldorf.de> Author: Matti Picus Branch: Changeset: r66987:6ecf84f62231 Date: 2013-09-17 09:43 +0300 http://bitbucket.org/pypy/pypy/changeset/6ecf84f62231/ Log: typo 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 @@ -82,7 +82,7 @@ .. branch: rewritten-loop-logging .. branch: no-release-gil .. branch: safe-win-mmap -.. branch: boolean-index-cleanup +.. branch: boolean-indexing-cleanup .. branch: nobold-backtrace Work on improving UnionError messages and stack trace displays. From noreply at buildbot.pypy.org Tue Sep 17 09:03:26 2013 From: noreply at buildbot.pypy.org (mattip) Date: Tue, 17 Sep 2013 09:03:26 +0200 (CEST) Subject: [pypy-commit] pypy default: indexing with boolean does not broadcast over all of array Message-ID: <20130917070326.816DD1C01B0@cobra.cs.uni-duesseldorf.de> Author: Matti Picus Branch: Changeset: r66988:5df0779e41d1 Date: 2013-09-17 10:02 +0300 http://bitbucket.org/pypy/pypy/changeset/5df0779e41d1/ Log: indexing with boolean does not broadcast over all of 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 @@ -95,7 +95,7 @@ if idx.get_size() > self.get_size(): raise OperationError(space.w_ValueError, space.wrap("index out of range for array")) - idx_iter = idx.create_iter(self.get_shape()) + idx_iter = idx.create_iter() size = loop.count_all_true_iter(idx_iter, self.get_shape(), idx.get_dtype()) if size > val.get_size() and val.get_size() > 1: raise OperationError(space.w_ValueError, space.wrap("NumPy boolean array indexing assignment " From noreply at buildbot.pypy.org Tue Sep 17 16:26:10 2013 From: noreply at buildbot.pypy.org (fijal) Date: Tue, 17 Sep 2013 16:26:10 +0200 (CEST) Subject: [pypy-commit] pypy file-support-in-rpython: start supporting open() in RPython Message-ID: <20130917142610.EBD731C01B0@cobra.cs.uni-duesseldorf.de> Author: Maciej Fijalkowski Branch: file-support-in-rpython Changeset: r66989:6354377ad204 Date: 2013-09-17 16:25 +0200 http://bitbucket.org/pypy/pypy/changeset/6354377ad204/ Log: start supporting open() in RPython diff --git a/rpython/rlib/rfile.py b/rpython/rlib/rfile.py new file mode 100644 --- /dev/null +++ b/rpython/rlib/rfile.py @@ -0,0 +1,33 @@ + +""" This file makes open() and friends RPython +""" + +from rpython.annotator.model import SomeObject, SomeString +from rpython.rtyper.extregistry import ExtRegistryEntry + +class SomeFile(SomeObject): + def method_write(self, s_arg): + assert isinstance(s_arg, SomeString) + + def method_close(self): + pass + + def rtyper_makekey(self): + return self.__class__, + + def rtyper_makerepr(self, rtyper): + from rpython.rtyper.lltypesystem.rfile import FileRepr + + return FileRepr(rtyper) + +class FileEntry(ExtRegistryEntry): + _about_ = open + + def compute_result_annotation(self, s_name, s_mode=None): + assert isinstance(s_name, SomeString) + if s_mode is not None: + assert isinstance(s_mode, SomeString) + return SomeFile() + + def specialize_call(self, hop): + return hop.r_result.rtype_constructor(hop) diff --git a/rpython/rlib/test/test_rfile.py b/rpython/rlib/test/test_rfile.py new file mode 100644 --- /dev/null +++ b/rpython/rlib/test/test_rfile.py @@ -0,0 +1,16 @@ + +from rpython.rtyper.test.tool import BaseRtypingTest +from rpython.tool.udir import udir +from rpython.rlib import rfile + +class TestFile(BaseRtypingTest): + def test_open(self): + fname = str(udir.join('test_file', 'file_1')) + + def f(): + f = open(fname, "w") + f.write("dupa") + f.close() + + self.interpret(f, []) + assert open(fname, "r").read() == "dupa" diff --git a/rpython/rtyper/lltypesystem/rfile.py b/rpython/rtyper/lltypesystem/rfile.py new file mode 100644 --- /dev/null +++ b/rpython/rtyper/lltypesystem/rfile.py @@ -0,0 +1,59 @@ + +import os +from rpython.rlib import rposix +from rpython.rtyper.rtyper import Repr +from rpython.rtyper.lltypesystem import lltype, rffi +from rpython.rtyper.lltypesystem.rstr import string_repr +from rpython.translator.tool.cbuild import ExternalCompilationInfo +from rpython.rtyper.annlowlevel import hlstr + +FILE = lltype.Struct('FILE') # opaque type maybe +FILE_WRAPPER = lltype.GcStruct("FileWrapper", ('file', lltype.Ptr(FILE))) + +eci = ExternalCompilationInfo(includes=['stdio.h']) + +c_open = rffi.llexternal('fopen', [rffi.CCHARP, rffi.CCHARP], + lltype.Ptr(FILE), compilation_info=eci) + +def ll_open(name, mode): + file_wrapper = lltype.malloc(FILE_WRAPPER) + name = hlstr(name) + mode = hlstr(mode) + with rffi.scoped_str2charp(name) as ll_name: + with rffi.scoped_str2charp(mode) as ll_mode: + ll_f = c_open(ll_name, ll_mode) + if not ll_f: + errno = rposix.get_errno() + raise OSError(errno, os.strerror(errno)) + file_wrapper.file = ll_f + return file_wrapper + +def ll_write(file_wrapper, value): + value = hlstr(value) + with rffi.scoped_str2charp(value) as ll_value: + pass + +def ll_close(file_wrapper): + pass + +class FileRepr(Repr): + lowleveltype = lltype.Ptr(FILE_WRAPPER) + + def __init__(self, typer): + pass + + def rtype_constructor(self, hop): + arg_0 = hop.inputarg(string_repr, 0) + arg_1 = hop.inputarg(string_repr, 1) + hop.exception_is_here() + return hop.gendirectcall(ll_open, arg_0, arg_1) + + def rtype_method_write(self, hop): + args_v = hop.inputargs(self, string_repr) + hop.exception_is_here() + return hop.gendirectcall(ll_write, *args_v) + + def rtype_method_close(self, hop): + r_self = hop.inputarg(self, 0) + hop.exception_is_here() + return hop.gendirectcall(ll_close, r_self) From noreply at buildbot.pypy.org Tue Sep 17 20:20:00 2013 From: noreply at buildbot.pypy.org (fijal) Date: Tue, 17 Sep 2013 20:20:00 +0200 (CEST) Subject: [pypy-commit] pypy file-support-in-rpython: more support for files in RPython Message-ID: <20130917182000.A40191C0113@cobra.cs.uni-duesseldorf.de> Author: Maciej Fijalkowski Branch: file-support-in-rpython Changeset: r66990:e9d5d97ed6b6 Date: 2013-09-17 20:19 +0200 http://bitbucket.org/pypy/pypy/changeset/e9d5d97ed6b6/ Log: more support for files in RPython diff --git a/rpython/rlib/test/test_rfile.py b/rpython/rlib/test/test_rfile.py --- a/rpython/rlib/test/test_rfile.py +++ b/rpython/rlib/test/test_rfile.py @@ -4,8 +4,12 @@ from rpython.rlib import rfile class TestFile(BaseRtypingTest): + def setup_class(cls): + cls.tmpdir = udir.join('test_rfile') + cls.tmpdir.ensure(dir=True) + def test_open(self): - fname = str(udir.join('test_file', 'file_1')) + fname = str(self.tmpdir.join('file_1')) def f(): f = open(fname, "w") diff --git a/rpython/rtyper/lltypesystem/rfile.py b/rpython/rtyper/lltypesystem/rfile.py --- a/rpython/rtyper/lltypesystem/rfile.py +++ b/rpython/rtyper/lltypesystem/rfile.py @@ -1,11 +1,14 @@ import os from rpython.rlib import rposix +from rpython.rlib.rarithmetic import r_uint +from rpython.annotator import model as annmodel from rpython.rtyper.rtyper import Repr -from rpython.rtyper.lltypesystem import lltype, rffi -from rpython.rtyper.lltypesystem.rstr import string_repr +from rpython.rtyper.lltypesystem import lltype, rffi, llmemory +from rpython.rtyper.lltypesystem.rstr import string_repr, STR from rpython.translator.tool.cbuild import ExternalCompilationInfo from rpython.rtyper.annlowlevel import hlstr +from rpython.rtyper.lltypesystem.lloperation import llop FILE = lltype.Struct('FILE') # opaque type maybe FILE_WRAPPER = lltype.GcStruct("FileWrapper", ('file', lltype.Ptr(FILE))) @@ -14,39 +17,74 @@ c_open = rffi.llexternal('fopen', [rffi.CCHARP, rffi.CCHARP], lltype.Ptr(FILE), compilation_info=eci) +c_close = rffi.llexternal('fclose', [lltype.Ptr(FILE)], rffi.INT, + compilation_info=eci) +c_write = rffi.llexternal('fwrite', [rffi.CCHARP, rffi.SIZE_T, rffi.SIZE_T, + lltype.Ptr(FILE)], rffi.SIZE_T) def ll_open(name, mode): file_wrapper = lltype.malloc(FILE_WRAPPER) - name = hlstr(name) - mode = hlstr(mode) - with rffi.scoped_str2charp(name) as ll_name: - with rffi.scoped_str2charp(mode) as ll_mode: - ll_f = c_open(ll_name, ll_mode) - if not ll_f: - errno = rposix.get_errno() - raise OSError(errno, os.strerror(errno)) - file_wrapper.file = ll_f + ll_name = rffi.str2charp(name) + ll_mode = rffi.str2charp(mode) + try: + ll_f = c_open(ll_name, ll_mode) + if not ll_f: + errno = rposix.get_errno() + raise OSError(errno, os.strerror(errno)) + file_wrapper.file = ll_f + finally: + lltype.free(ll_name, flavor='raw') + lltype.free(ll_mode, flavor='raw') return file_wrapper def ll_write(file_wrapper, value): + ll_file = file_wrapper.file value = hlstr(value) - with rffi.scoped_str2charp(value) as ll_value: - pass + assert value is not None + ll_value = rffi.get_nonmovingbuffer(value) + try: + # NO GC OPERATIONS HERE + total_bytes = 0 + ll_current = ll_value + while total_bytes < len(value): + bytes = c_write(ll_current, 1, len(value) - r_uint(total_bytes), + ll_file) + if bytes == 0: + errno = rposix.get_errno() + raise OSError(errno, os.strerror(errno)) + total_bytes += bytes + ll_current = rffi.cast(rffi.CCHARP, + rffi.cast(lltype.Unsigned, ll_value) + + total_bytes) + finally: + rffi.free_nonmovingbuffer(value, ll_value) def ll_close(file_wrapper): - pass + if file_wrapper.file: + # double close is allowed + res = c_close(file_wrapper.file) + file_wrapper.file = lltype.nullptr(FILE) + if res == -1: + errno = rposix.get_errno() + raise OSError(errno, os.strerror(errno)) class FileRepr(Repr): lowleveltype = lltype.Ptr(FILE_WRAPPER) def __init__(self, typer): - pass + Repr.__init__(self) def rtype_constructor(self, hop): - arg_0 = hop.inputarg(string_repr, 0) - arg_1 = hop.inputarg(string_repr, 1) + repr = hop.rtyper.getrepr(annmodel.SomeString()) + arg_0 = hop.inputarg(repr, 0) + arg_1 = hop.inputarg(repr, 1) hop.exception_is_here() - return hop.gendirectcall(ll_open, arg_0, arg_1) + open = hop.rtyper.getannmixlevel().delayedfunction( + ll_open, [annmodel.SomeString()] * 2, + annmodel.SomePtr(self.lowleveltype)) + v_open = hop.inputconst(lltype.typeOf(open), open) + return hop.genop('direct_call', [v_open, arg_0, arg_1], + resulttype=self) def rtype_method_write(self, hop): args_v = hop.inputargs(self, string_repr) From noreply at buildbot.pypy.org Tue Sep 17 20:43:32 2013 From: noreply at buildbot.pypy.org (alex_gaynor) Date: Tue, 17 Sep 2013 20:43:32 +0200 (CEST) Subject: [pypy-commit] pypy default: Fixed some use of gendered language Message-ID: <20130917184332.C457D1C0113@cobra.cs.uni-duesseldorf.de> Author: Alex Gaynor Branch: Changeset: r66991:147d3d036eab Date: 2013-09-17 11:42 -0700 http://bitbucket.org/pypy/pypy/changeset/147d3d036eab/ Log: Fixed some use of gendered language diff --git a/pypy/doc/faq.rst b/pypy/doc/faq.rst --- a/pypy/doc/faq.rst +++ b/pypy/doc/faq.rst @@ -356,7 +356,7 @@ attempt to point newcomers at existing alternatives, which are more mainstream and where they will get help from many people.* - *If anybody seriously wants to promote RPython anyway, he is welcome + *If anybody seriously wants to promote RPython anyway, they are welcome to: we won't actively resist such a plan. There are a lot of things that could be done to make RPython a better Java-ish language for example, starting with supporting non-GIL-based multithreading, but we @@ -396,8 +396,8 @@ patch the generated machine code. So the position of the core PyPy developers is that if anyone wants to -make an N+1'th attempt with LLVM, he is welcome, and he will receive a -bit of help on the IRC channel, but he is left with the burden of proof +make an N+1'th attempt with LLVM, they are welcome, and will be happy to +provide help in the IRC channel, but they are left with the burden of proof that it works. ---------------------- From noreply at buildbot.pypy.org Wed Sep 18 01:26:33 2013 From: noreply at buildbot.pypy.org (pjenvey) Date: Wed, 18 Sep 2013 01:26:33 +0200 (CEST) Subject: [pypy-commit] pypy py3k: threadsafe -> releasegil Message-ID: <20130917232633.355651C027F@cobra.cs.uni-duesseldorf.de> Author: Philip Jenvey Branch: py3k Changeset: r66992:f1a61a8e481b Date: 2013-09-17 15:23 -0700 http://bitbucket.org/pypy/pypy/changeset/f1a61a8e481b/ Log: threadsafe -> releasegil 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 @@ -44,17 +44,17 @@ lltype.Ptr(lltype.FuncType([rffi.VOIDP], rffi.INT)), rffi.VOIDP], lltype.Void, compilation_info=eci, - threadsafe=True) + releasegil=True) c_cloexec_pipe = rffi.llexternal( 'pypy_subprocess_cloexec_pipe', [rffi.CArrayPtr(rffi.INT)], rffi.INT, compilation_info=eci, - threadsafe=True) + releasegil=True) c_init = rffi.llexternal( 'pypy_subprocess_init', [], lltype.Void, compilation_info=eci, - threadsafe=True) + releasegil=True) class PreexecCallback: From noreply at buildbot.pypy.org Wed Sep 18 01:26:34 2013 From: noreply at buildbot.pypy.org (pjenvey) Date: Wed, 18 Sep 2013 01:26:34 +0200 (CEST) Subject: [pypy-commit] pypy py3k: issue #1603: fix the default get_printable_location potentially releasing the Message-ID: <20130917232634.6C7B41C0710@cobra.cs.uni-duesseldorf.de> Author: Philip Jenvey Branch: py3k Changeset: r66993:464c7c15c57c Date: 2013-09-17 16:25 -0700 http://bitbucket.org/pypy/pypy/changeset/464c7c15c57c/ Log: issue #1603: fix the default get_printable_location potentially releasing the GIL via get_repr diff --git a/pypy/interpreter/pycode.py b/pypy/interpreter/pycode.py --- a/pypy/interpreter/pycode.py +++ b/pypy/interpreter/pycode.py @@ -417,13 +417,17 @@ return space.newtuple([new_inst, space.newtuple(tup)]) def get_repr(self): + # This is called by the default get_printable_location so it + # must avoid doing too much (that might release the gil) + return '' % ( + self.co_name, self.co_filename, + -1 if self.co_firstlineno == 0 else self.co_firstlineno) + + def repr(self, space): 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'' % ( + return space.wrap(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()) + -1 if self.co_firstlineno == 0 else self.co_firstlineno)) 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 @@ -31,10 +31,7 @@ from pypy.tool.stdlib_opcode import opcode_method_names from rpython.rlib.runicode import unicode_encode_utf_8 name = opcode_method_names[ord(bytecode.co_code[next_instr])] - repru = bytecode.get_repr() - # XXX: lame - reprs = unicode_encode_utf_8(repru, len(repru), "replace") - return '%s #%d %s' % (reprs, next_instr, name) + return '%s #%d %s' % (bytecode.get_repr(), next_instr, name) def get_jitcell_at(next_instr, is_being_profiled, bytecode): # use only uints as keys in the jit_cells dict, rather than From noreply at buildbot.pypy.org Wed Sep 18 08:13:41 2013 From: noreply at buildbot.pypy.org (mattip) Date: Wed, 18 Sep 2013 08:13:41 +0200 (CEST) Subject: [pypy-commit] pypy default: wrong arg passed to jitdriver Message-ID: <20130918061341.786401C0113@cobra.cs.uni-duesseldorf.de> Author: Matti Picus Branch: Changeset: r66994:29adbad234d9 Date: 2013-09-18 09:12 +0300 http://bitbucket.org/pypy/pypy/changeset/29adbad234d9/ Log: wrong arg passed to jitdriver 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 @@ -96,7 +96,7 @@ raise OperationError(space.w_ValueError, space.wrap("index out of range for array")) idx_iter = idx.create_iter() - size = loop.count_all_true_iter(idx_iter, self.get_shape(), idx.get_dtype()) + size = loop.count_all_true_iter(idx_iter, idx.get_shape(), idx.get_dtype()) if size > val.get_size() and val.get_size() > 1: raise OperationError(space.w_ValueError, space.wrap("NumPy boolean array indexing assignment " "cannot assign %d input values to " From noreply at buildbot.pypy.org Wed Sep 18 10:36:41 2013 From: noreply at buildbot.pypy.org (Raemi) Date: Wed, 18 Sep 2013 10:36:41 +0200 (CEST) Subject: [pypy-commit] pypy stmgc-c4: slightly better code-generation for ptr_eq in case of NULL checks Message-ID: <20130918083641.D98381C1500@cobra.cs.uni-duesseldorf.de> Author: Remi Meier Branch: stmgc-c4 Changeset: r66995:a1ca6b062faf Date: 2013-09-13 14:04 +0200 http://bitbucket.org/pypy/pypy/changeset/a1ca6b062faf/ Log: slightly better code-generation for ptr_eq in case of NULL checks 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 @@ -2313,50 +2313,49 @@ mc.J_il8(rx86.Conditions['NZ'], 0) j_ok1 = mc.get_relative_pos() + skip = False # a == 0 || b == 0 -> SET Z + j_ok2 = 0 if isinstance(a_base, ImmedLoc): if a_base.getint() == 0: # set Z flag: mc.XOR(X86_64_SCRATCH_REG, X86_64_SCRATCH_REG) - mc.JMP_l8(0) - j_ok2 = mc.get_relative_pos() - else: - j_ok2 = 0 + skip = True else: mc.CMP(a_base, imm(0)) mc.J_il8(rx86.Conditions['Z'], 0) j_ok2 = mc.get_relative_pos() # - if isinstance(b_base, ImmedLoc): - if b_base.getint() == 0: - # set Z flag: - mc.XOR(X86_64_SCRATCH_REG, X86_64_SCRATCH_REG) - mc.JMP_l8(0) + j_ok3 = 0 + if not skip: + if isinstance(b_base, ImmedLoc): + if b_base.getint() == 0: + # set Z flag: + mc.XOR(X86_64_SCRATCH_REG, X86_64_SCRATCH_REG) + skip = True + else: + mc.CMP(b_base, imm(0)) + mc.J_il8(rx86.Conditions['Z'], 0) j_ok3 = mc.get_relative_pos() - else: - j_ok3 = 0 - else: - mc.CMP(b_base, imm(0)) - mc.J_il8(rx86.Conditions['Z'], 0) - j_ok3 = mc.get_relative_pos() - # a.type != b.type - # XXX: todo, if it ever happens.. - - # - # SLOWPATH - # - mc.PUSH(b_base) - mc.PUSH(a_base) - func = self.ptr_eq_slowpath - mc.CALL(imm(func)) - # result still on stack - mc.POP_r(X86_64_SCRATCH_REG.value) - # _Bool return type only sets lower 8 bits of return value - sl = X86_64_SCRATCH_REG.lowest8bits() - mc.TEST8_rr(sl.value, sl.value) - # - # END SLOWPATH - # + # a.type != b.type + # XXX: todo, if it ever happens.. + + # + # SLOWPATH + # + if not skip: + mc.PUSH(b_base) + mc.PUSH(a_base) + func = self.ptr_eq_slowpath + mc.CALL(imm(func)) + # result still on stack + mc.POP_r(X86_64_SCRATCH_REG.value) + # _Bool return type only sets lower 8 bits of return value + sl = X86_64_SCRATCH_REG.lowest8bits() + mc.TEST8_rr(sl.value, sl.value) + # + # END SLOWPATH + # # OK: flags already set if j_ok1: From noreply at buildbot.pypy.org Wed Sep 18 10:36:43 2013 From: noreply at buildbot.pypy.org (Raemi) Date: Wed, 18 Sep 2013 10:36:43 +0200 (CEST) Subject: [pypy-commit] pypy stmgc-c4: stm: remove redundant fallback to inevitable in stmrewrite Message-ID: <20130918083643.4318F1C1500@cobra.cs.uni-duesseldorf.de> Author: Remi Meier Branch: stmgc-c4 Changeset: r66996:a80fc85febae Date: 2013-09-18 10:35 +0200 http://bitbucket.org/pypy/pypy/changeset/a80fc85febae/ Log: stm: remove redundant fallback to inevitable in stmrewrite diff --git a/rpython/jit/backend/llsupport/stmrewrite.py b/rpython/jit/backend/llsupport/stmrewrite.py --- a/rpython/jit/backend/llsupport/stmrewrite.py +++ b/rpython/jit/backend/llsupport/stmrewrite.py @@ -105,10 +105,14 @@ # ---------- calls ---------- if op.is_call(): if op.getopnum() == rop.CALL_RELEASE_GIL: - self.fallback_inevitable(op) + # self.fallback_inevitable(op) + # done by assembler._release_gil_shadowstack() + self.newops.append(op) elif op.getopnum() == rop.CALL_ASSEMBLER: self.handle_call_assembler(op) else: + # only insert become_inevitable if calling a + # non-transactionsafe and non-releasegil function descr = op.getdescr() assert not descr or isinstance(descr, CallDescr) if not descr or not descr.get_extra_info() \ From noreply at buildbot.pypy.org Wed Sep 18 11:59:01 2013 From: noreply at buildbot.pypy.org (fijal) Date: Wed, 18 Sep 2013 11:59:01 +0200 (CEST) Subject: [pypy-commit] pypy file-support-in-rpython: support more of read/write Message-ID: <20130918095901.5E0781C14DF@cobra.cs.uni-duesseldorf.de> Author: Maciej Fijalkowski Branch: file-support-in-rpython Changeset: r66997:ff5bcd269204 Date: 2013-09-18 11:58 +0200 http://bitbucket.org/pypy/pypy/changeset/ff5bcd269204/ Log: support more of read/write diff --git a/rpython/rlib/rfile.py b/rpython/rlib/rfile.py --- a/rpython/rlib/rfile.py +++ b/rpython/rlib/rfile.py @@ -2,13 +2,18 @@ """ This file makes open() and friends RPython """ -from rpython.annotator.model import SomeObject, SomeString +from rpython.annotator.model import SomeObject, SomeString, SomeInteger from rpython.rtyper.extregistry import ExtRegistryEntry class SomeFile(SomeObject): def method_write(self, s_arg): assert isinstance(s_arg, SomeString) + def method_read(self, s_arg=None): + if s_arg is not None: + assert isinstance(s_arg, SomeInteger) + return SomeString(can_be_None=False) + def method_close(self): pass diff --git a/rpython/rlib/test/test_rfile.py b/rpython/rlib/test/test_rfile.py --- a/rpython/rlib/test/test_rfile.py +++ b/rpython/rlib/test/test_rfile.py @@ -18,3 +18,38 @@ self.interpret(f, []) assert open(fname, "r").read() == "dupa" + + def test_read_write(self): + fname = str(self.tmpdir.join('file_2')) + + def f(): + f = open(fname, "w") + f.write("dupa") + f.close() + f2 = open(fname) + dupa = f2.read() + assert dupa == "dupa" + f2.close() + + self.interpret(f, []) + + def test_read_sequentially(self): + fname = self.tmpdir.join('file_3') + fname.write("dupa") + fname = str(fname) + + def f(): + f = open(fname) + a = f.read(1) + b = f.read(1) + c = f.read(1) + d = f.read(1) + e = f.read() + f.close() + assert a == "d" + assert b == "u" + assert c == "p" + assert d == "a" + assert e == "" + + self.interpret(f, []) diff --git a/rpython/rtyper/lltypesystem/rfile.py b/rpython/rtyper/lltypesystem/rfile.py --- a/rpython/rtyper/lltypesystem/rfile.py +++ b/rpython/rtyper/lltypesystem/rfile.py @@ -4,6 +4,7 @@ from rpython.rlib.rarithmetic import r_uint from rpython.annotator import model as annmodel from rpython.rtyper.rtyper import Repr +from rpython.rlib.rstring import StringBuilder from rpython.rtyper.lltypesystem import lltype, rffi, llmemory from rpython.rtyper.lltypesystem.rstr import string_repr, STR from rpython.translator.tool.cbuild import ExternalCompilationInfo @@ -21,6 +22,11 @@ compilation_info=eci) c_write = rffi.llexternal('fwrite', [rffi.CCHARP, rffi.SIZE_T, rffi.SIZE_T, lltype.Ptr(FILE)], rffi.SIZE_T) +c_read = rffi.llexternal('fread', [rffi.CCHARP, rffi.SIZE_T, rffi.SIZE_T, + lltype.Ptr(FILE)], rffi.SIZE_T) +c_feof = rffi.llexternal('feof', [lltype.Ptr(FILE)], rffi.INT) +c_ferror = rffi.llexternal('ferror', [lltype.Ptr(FILE)], rffi.INT) +c_clearerror = rffi.llexternal('clearerr', [lltype.Ptr(FILE)], lltype.Void) def ll_open(name, mode): file_wrapper = lltype.malloc(FILE_WRAPPER) @@ -39,11 +45,14 @@ def ll_write(file_wrapper, value): ll_file = file_wrapper.file + if not ll_file: + raise ValueError("I/O operation on closed file") value = hlstr(value) assert value is not None ll_value = rffi.get_nonmovingbuffer(value) try: - # NO GC OPERATIONS HERE + # note that since we got a nonmoving buffer, it is either raw + # or already cannot move, so the arithmetics below are fine total_bytes = 0 ll_current = ll_value while total_bytes < len(value): @@ -59,6 +68,43 @@ finally: rffi.free_nonmovingbuffer(value, ll_value) +BASE_BUF_SIZE = 4096 + +def ll_read(file_wrapper, size): + ll_file = file_wrapper.file + if not ll_file: + raise ValueError("I/O operation on closed file") + if size < 0: + # read the entire contents + buf = lltype.malloc(rffi.CCHARP.TO, BASE_BUF_SIZE, flavor='raw') + try: + s = StringBuilder() + while True: + returned_size = c_read(buf, 1, BASE_BUF_SIZE, ll_file) + if returned_size == 0: + if c_feof(ll_file): + # ok, finished + return s.build() + errno = c_ferror(ll_file) + c_clearerror(ll_file) + raise OSError(errno, os.strerror(errno)) + s.append_charpsize(buf, returned_size) + finally: + lltype.free(buf, flavor='raw') + else: + raw_buf, gc_buf = rffi.alloc_buffer(size) + try: + returned_size = c_read(raw_buf, 1, size, ll_file) + if returned_size == 0: + if not c_feof(ll_file): + errno = c_ferror(ll_file) + raise OSError(errno, os.strerror(errno)) + s = rffi.str_from_buffer(raw_buf, gc_buf, size, + rffi.cast(lltype.Signed, returned_size)) + finally: + rffi.keep_buffer_alive_until_here(raw_buf, gc_buf) + return s + def ll_close(file_wrapper): if file_wrapper.file: # double close is allowed @@ -77,7 +123,10 @@ def rtype_constructor(self, hop): repr = hop.rtyper.getrepr(annmodel.SomeString()) arg_0 = hop.inputarg(repr, 0) - arg_1 = hop.inputarg(repr, 1) + if len(hop.args_v) == 1: + arg_1 = hop.inputconst(string_repr, "r") + else: + arg_1 = hop.inputarg(repr, 1) hop.exception_is_here() open = hop.rtyper.getannmixlevel().delayedfunction( ll_open, [annmodel.SomeString()] * 2, @@ -95,3 +144,12 @@ r_self = hop.inputarg(self, 0) hop.exception_is_here() return hop.gendirectcall(ll_close, r_self) + + def rtype_method_read(self, hop): + r_self = hop.inputarg(self, 0) + if len(hop.args_v) != 2: + arg_1 = hop.inputconst(lltype.Signed, -1) + else: + arg_1 = hop.inputarg(lltype.Signed, 1) + hop.exception_is_here() + return hop.gendirectcall(ll_read, r_self, arg_1) From noreply at buildbot.pypy.org Wed Sep 18 12:26:02 2013 From: noreply at buildbot.pypy.org (fijal) Date: Wed, 18 Sep 2013 12:26:02 +0200 (CEST) Subject: [pypy-commit] pypy default: ctermid impl in rpython, no idea how to test it Message-ID: <20130918102602.D22391C01B0@cobra.cs.uni-duesseldorf.de> Author: Maciej Fijalkowski Branch: Changeset: r66998:c5f2ba2568ae Date: 2013-09-18 12:21 +0200 http://bitbucket.org/pypy/pypy/changeset/c5f2ba2568ae/ Log: ctermid impl in rpython, no idea how to test it 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 @@ -1668,6 +1668,16 @@ return extdef([int], int, llimpl=nice_llimpl, export_name="ll_os.ll_os_nice") + @registering_if(os, 'ctermid') + def register_os_ctermid(self): + os_ctermid = self.llexternal('ctermid', [rffi.CCHARP], rffi.CCHARP) + + def ctermid_llimpl(): + return rffi.charp2str(os_ctermid(lltype.nullptr(rffi.CCHARP.TO))) + + return extdef([], str, llimpl=ctermid_llimpl, + export_name="ll_os.ll_os_ctermid") + # --------------------------- os.stat & variants --------------------------- @registering(os.fstat) From noreply at buildbot.pypy.org Wed Sep 18 12:26:04 2013 From: noreply at buildbot.pypy.org (fijal) Date: Wed, 18 Sep 2013 12:26:04 +0200 (CEST) Subject: [pypy-commit] pypy default: merge Message-ID: <20130918102604.CD09F1C14DF@cobra.cs.uni-duesseldorf.de> Author: Maciej Fijalkowski Branch: Changeset: r66999:91a199b6f1fd Date: 2013-09-18 12:23 +0200 http://bitbucket.org/pypy/pypy/changeset/91a199b6f1fd/ Log: merge diff --git a/lib-python/2.7/uuid.py b/lib-python/2.7/uuid.py --- a/lib-python/2.7/uuid.py +++ b/lib-python/2.7/uuid.py @@ -128,10 +128,10 @@ """ if hex is not None: - if (bytes is not None or bytes_le is not None or fields is not None - or int is not None): - raise TypeError('if the hex argument is given, bytes, bytes_le, fields,' - ' and int need to be None') + if (bytes is not None or bytes_le is not None or + fields is not None or int is not None): + raise TypeError('if the hex argument is given, bytes,' + ' bytes_le, fields, and int need to be None') hex = hex.replace('urn:', '').replace('uuid:', '') hex = hex.strip('{}').replace('-', '') if len(hex) != 32: @@ -139,8 +139,8 @@ int = long(hex, 16) elif bytes_le is not None: if bytes is not None or fields is not None or int is not None: - raise TypeError('if the bytes_le argument is given, bytes, fields,' - ' and int need to be None') + raise TypeError('if the bytes_le argument is given, bytes,' + ' fields, and int need to be None') if len(bytes_le) != 16: raise ValueError('bytes_le is not a 16-char string') bytes = (bytes_le[3] + bytes_le[2] + bytes_le[1] + bytes_le[0] + @@ -150,15 +150,16 @@ struct.unpack('>Q', bytes[8:])[0]) elif bytes is not None: if fields is not None or int is not None: - raise TypeError('if the bytes argument is given, fields' - ' and int need to be None') + raise TypeError('if the bytes argument is given, fields ' + 'and int need to be None') if len(bytes) != 16: raise ValueError('bytes is not a 16-char string') int = (struct.unpack('>Q', bytes[:8])[0] << 64 | struct.unpack('>Q', bytes[8:])[0]) elif fields is not None: if int is not None: - raise TypeError('if the fields argument is given, int needs to be None') + raise TypeError('if the fields argument is given, int needs' + ' to be None') if len(fields) != 6: raise ValueError('fields is not a 6-tuple') (time_low, time_mid, time_hi_version, diff --git a/pypy/doc/faq.rst b/pypy/doc/faq.rst --- a/pypy/doc/faq.rst +++ b/pypy/doc/faq.rst @@ -356,7 +356,7 @@ attempt to point newcomers at existing alternatives, which are more mainstream and where they will get help from many people.* - *If anybody seriously wants to promote RPython anyway, he is welcome + *If anybody seriously wants to promote RPython anyway, they are welcome to: we won't actively resist such a plan. There are a lot of things that could be done to make RPython a better Java-ish language for example, starting with supporting non-GIL-based multithreading, but we @@ -396,8 +396,8 @@ patch the generated machine code. So the position of the core PyPy developers is that if anyone wants to -make an N+1'th attempt with LLVM, he is welcome, and he will receive a -bit of help on the IRC channel, but he is left with the burden of proof +make an N+1'th attempt with LLVM, they are welcome, and will be happy to +provide help in the IRC channel, but they are left with the burden of proof that it works. ---------------------- 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 @@ -81,6 +81,8 @@ .. branch: numpypy-inplace-op .. branch: rewritten-loop-logging .. branch: no-release-gil +.. branch: safe-win-mmap +.. branch: boolean-indexing-cleanup .. branch: nobold-backtrace Work on improving UnionError messages and stack trace displays. 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 @@ -316,7 +316,8 @@ self.storage = storage def create_iter(self, shape=None, backward_broadcast=False): - if shape is None or shape == self.get_shape(): + if shape is None or \ + support.product(shape) <= support.product(self.get_shape()): return iter.ConcreteArrayIterator(self) r = calculate_broadcast_strides(self.get_strides(), self.get_backstrides(), @@ -385,7 +386,8 @@ loop.fill(self, box.convert_to(self.dtype)) def create_iter(self, shape=None, backward_broadcast=False): - if shape is not None and shape != self.get_shape(): + if shape is not None and shape != self.get_shape() and \ + support.product(shape) > support.product(self.get_shape()): r = calculate_broadcast_strides(self.get_strides(), self.get_backstrides(), self.get_shape(), shape, 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 @@ -88,28 +88,22 @@ w_res = W_NDimArray.from_shape(space, res_shape, self.get_dtype(), w_instance=self) return loop.getitem_filter(w_res, self, arr) - def setitem_filter(self, space, idx, value): - from pypy.module.micronumpy.interp_boxes import Box - val = value + def setitem_filter(self, space, idx, val): if len(idx.get_shape()) > 1 and idx.get_shape() != self.get_shape(): raise OperationError(space.w_ValueError, space.wrap("boolean index array should have 1 dimension")) if idx.get_size() > self.get_size(): raise OperationError(space.w_ValueError, space.wrap("index out of range for array")) - idx_iter = idx.create_iter(self.get_shape()) - size = loop.count_all_true_iter(idx_iter, self.get_shape(), idx.get_dtype()) - if len(val.get_shape()) > 0 and val.get_shape()[0] > 1 and size > val.get_shape()[0]: + idx_iter = idx.create_iter() + size = loop.count_all_true_iter(idx_iter, idx.get_shape(), idx.get_dtype()) + if size > val.get_size() and val.get_size() > 1: raise OperationError(space.w_ValueError, space.wrap("NumPy boolean array indexing assignment " "cannot assign %d input values to " - "the %d output values where the mask is true" % (val.get_shape()[0],size))) - if val.get_shape() == [1]: - box = val.descr_getitem(space, space.wrap(0)) - assert isinstance(box, Box) - val = W_NDimArray(scalar.Scalar(val.get_dtype(), box)) - elif val.get_shape() == [0]: + "the %d output values where the mask is true" % (val.get_size(), size))) + if val.get_shape() == [0]: val.implementation.dtype = self.implementation.dtype - loop.setitem_filter(self, idx, val) + loop.setitem_filter(self, idx, val, size) def _prepare_array_index(self, space, w_index): if isinstance(w_index, W_NDimArray): 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 @@ -372,10 +372,10 @@ 'index_dtype'], reds = 'auto') -def setitem_filter(arr, index, value): +def setitem_filter(arr, index, value, size): arr_iter = arr.create_iter() index_iter = index.create_iter(arr.get_shape()) - value_iter = value.create_iter() + value_iter = value.create_iter([size]) shapelen = len(arr.get_shape()) index_dtype = index.get_dtype() arr_dtype = arr.get_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 @@ -2355,11 +2355,16 @@ def test_array_indexing_bool_specialcases(self): from numpypy import arange, array a = arange(6) - try: - a[a < 3] = [1, 2] - assert False, "Should not work" - except ValueError: - pass + exc = raises(ValueError,'a[a < 3] = [1, 2]') + assert exc.value[0].find('cannot assign') >= 0 + b = arange(4).reshape(2, 2) + 10 + a[a < 4] = b + assert (a == [10, 11, 12, 13, 4, 5]).all() + b += 10 + c = arange(8).reshape(2, 2, 2) + a[a > 9] = c[:, :, 1] + assert (c[:, :, 1] == [[1, 3], [5, 7]]).all() + assert (a == [1, 3, 5, 7, 4, 5]).all() a = arange(6) a[a > 3] = array([15]) assert (a == [0, 1, 2, 3, 15, 15]).all() diff --git a/rpython/rlib/rmmap.py b/rpython/rlib/rmmap.py --- a/rpython/rlib/rmmap.py +++ b/rpython/rlib/rmmap.py @@ -118,10 +118,16 @@ return unsafe, safe def winexternal(name, args, result, **kwargs): - return rffi.llexternal(name, args, result, + unsafe = rffi.llexternal(name, args, result, compilation_info=CConfig._compilation_info_, calling_conv='win', **kwargs) + safe = rffi.llexternal(name, args, result, + compilation_info=CConfig._compilation_info_, + calling_conv='win', + sandboxsafe=True, releasegil=False, + **kwargs) + return unsafe, safe PTR = rffi.CCHARP @@ -188,32 +194,29 @@ SYSTEM_INFO = config['SYSTEM_INFO'] SYSTEM_INFO_P = lltype.Ptr(SYSTEM_INFO) - GetSystemInfo = winexternal('GetSystemInfo', [SYSTEM_INFO_P], lltype.Void) - GetFileSize = winexternal('GetFileSize', [HANDLE, LPDWORD], DWORD) - GetCurrentProcess = winexternal('GetCurrentProcess', [], HANDLE) - DuplicateHandle = winexternal('DuplicateHandle', [HANDLE, HANDLE, HANDLE, LPHANDLE, DWORD, BOOL, DWORD], BOOL) - CreateFileMapping = winexternal('CreateFileMappingA', [HANDLE, rwin32.LPSECURITY_ATTRIBUTES, DWORD, DWORD, DWORD, LPCSTR], HANDLE) - MapViewOfFile = winexternal('MapViewOfFile', [HANDLE, DWORD, DWORD, DWORD, SIZE_T], LPCSTR)##!!LPVOID) - UnmapViewOfFile = winexternal('UnmapViewOfFile', [LPCSTR], BOOL, - releasegil=False) - FlushViewOfFile = winexternal('FlushViewOfFile', [LPCSTR, SIZE_T], BOOL) - SetFilePointer = winexternal('SetFilePointer', [HANDLE, LONG, PLONG, DWORD], DWORD) - SetEndOfFile = winexternal('SetEndOfFile', [HANDLE], BOOL) - VirtualAlloc = winexternal('VirtualAlloc', + GetSystemInfo, _ = winexternal('GetSystemInfo', [SYSTEM_INFO_P], lltype.Void) + GetFileSize, _ = winexternal('GetFileSize', [HANDLE, LPDWORD], DWORD) + GetCurrentProcess, _ = winexternal('GetCurrentProcess', [], HANDLE) + DuplicateHandle, _ = winexternal('DuplicateHandle', [HANDLE, HANDLE, HANDLE, LPHANDLE, DWORD, BOOL, DWORD], BOOL) + CreateFileMapping, _ = winexternal('CreateFileMappingA', [HANDLE, rwin32.LPSECURITY_ATTRIBUTES, DWORD, DWORD, DWORD, LPCSTR], HANDLE) + MapViewOfFile, _ = winexternal('MapViewOfFile', [HANDLE, DWORD, DWORD, DWORD, SIZE_T], LPCSTR)##!!LPVOID) + _, UnmapViewOfFile_safe = winexternal('UnmapViewOfFile', [LPCSTR], BOOL) + FlushViewOfFile, _ = winexternal('FlushViewOfFile', [LPCSTR, SIZE_T], BOOL) + SetFilePointer, _ = winexternal('SetFilePointer', [HANDLE, LONG, PLONG, DWORD], DWORD) + SetEndOfFile, _ = winexternal('SetEndOfFile', [HANDLE], BOOL) + VirtualAlloc, VirtualAlloc_safe = winexternal('VirtualAlloc', [rffi.VOIDP, rffi.SIZE_T, DWORD, DWORD], rffi.VOIDP) - # VirtualProtect is used in llarena and should not release the GIL - _VirtualProtect = winexternal('VirtualProtect', + _, _VirtualProtect_safe = winexternal('VirtualProtect', [rffi.VOIDP, rffi.SIZE_T, DWORD, LPDWORD], - BOOL, - _nowrapper=True) + BOOL) def VirtualProtect(addr, size, mode, oldmode_ptr): - return _VirtualProtect(addr, + return _VirtualProtect_safe(addr, rffi.cast(rffi.SIZE_T, size), rffi.cast(DWORD, mode), oldmode_ptr) VirtualProtect._annspecialcase_ = 'specialize:ll' - VirtualFree = winexternal('VirtualFree', + VirtualFree, VirtualFree_safe = winexternal('VirtualFree', [rffi.VOIDP, rffi.SIZE_T, DWORD], BOOL) def _get_page_size(): @@ -300,7 +303,7 @@ def unmap(self): if _MS_WINDOWS: - UnmapViewOfFile(self.getptr(0)) + UnmapViewOfFile_safe(self.getptr(0)) elif _POSIX: self.unmap_range(0, self.size) @@ -575,6 +578,7 @@ def getitem(self, index): # simplified version, for rpython + self.check_valid() if index < 0: index += self.size return self.data[index] @@ -846,7 +850,7 @@ case of a sandboxed process """ null = lltype.nullptr(rffi.VOIDP.TO) - res = VirtualAlloc(null, map_size, MEM_COMMIT | MEM_RESERVE, + res = VirtualAlloc_safe(null, map_size, MEM_COMMIT | MEM_RESERVE, PAGE_EXECUTE_READWRITE) if not res: raise MemoryError @@ -858,6 +862,6 @@ alloc._annenforceargs_ = (int,) def free(ptr, map_size): - VirtualFree(ptr, 0, MEM_RELEASE) + VirtualFree_safe(ptr, 0, MEM_RELEASE) # register_external here? diff --git a/rpython/rtyper/lltypesystem/llarena.py b/rpython/rtyper/lltypesystem/llarena.py --- a/rpython/rtyper/lltypesystem/llarena.py +++ b/rpython/rtyper/lltypesystem/llarena.py @@ -535,6 +535,7 @@ else: from rpython.rlib.rmmap import PAGE_READWRITE as newprotect arg = lltype.malloc(LPDWORD.TO, 1, zero=True, flavor='raw') + #does not release the GIL VirtualProtect(rffi.cast(rffi.VOIDP, addr), size, newprotect, arg) # ignore potential errors diff --git a/rpython/rtyper/tool/rffi_platform.py b/rpython/rtyper/tool/rffi_platform.py --- a/rpython/rtyper/tool/rffi_platform.py +++ b/rpython/rtyper/tool/rffi_platform.py @@ -844,6 +844,10 @@ library_dir = '' libraries = ['gc64_dll'] includes = ['gc.h'] + # since config_external_library does not use a platform kwarg, + # somehow using a platform kw arg make the merge fail in + # config_external_library + platform = None else: library_dir = '' libraries = ['gc', 'dl'] From noreply at buildbot.pypy.org Wed Sep 18 14:25:08 2013 From: noreply at buildbot.pypy.org (fijal) Date: Wed, 18 Sep 2013 14:25:08 +0200 (CEST) Subject: [pypy-commit] pypy file-support-in-rpython: merge default Message-ID: <20130918122508.B899F1C01B0@cobra.cs.uni-duesseldorf.de> Author: Maciej Fijalkowski Branch: file-support-in-rpython Changeset: r67000:809f23f2a961 Date: 2013-09-18 13:31 +0200 http://bitbucket.org/pypy/pypy/changeset/809f23f2a961/ Log: merge default diff --git a/lib-python/2.7/uuid.py b/lib-python/2.7/uuid.py --- a/lib-python/2.7/uuid.py +++ b/lib-python/2.7/uuid.py @@ -128,10 +128,10 @@ """ if hex is not None: - if (bytes is not None or bytes_le is not None or fields is not None - or int is not None): - raise TypeError('if the hex argument is given, bytes, bytes_le, fields,' - ' and int need to be None') + if (bytes is not None or bytes_le is not None or + fields is not None or int is not None): + raise TypeError('if the hex argument is given, bytes,' + ' bytes_le, fields, and int need to be None') hex = hex.replace('urn:', '').replace('uuid:', '') hex = hex.strip('{}').replace('-', '') if len(hex) != 32: @@ -139,8 +139,8 @@ int = long(hex, 16) elif bytes_le is not None: if bytes is not None or fields is not None or int is not None: - raise TypeError('if the bytes_le argument is given, bytes, fields,' - ' and int need to be None') + raise TypeError('if the bytes_le argument is given, bytes,' + ' fields, and int need to be None') if len(bytes_le) != 16: raise ValueError('bytes_le is not a 16-char string') bytes = (bytes_le[3] + bytes_le[2] + bytes_le[1] + bytes_le[0] + @@ -150,15 +150,16 @@ struct.unpack('>Q', bytes[8:])[0]) elif bytes is not None: if fields is not None or int is not None: - raise TypeError('if the bytes argument is given, fields' - ' and int need to be None') + raise TypeError('if the bytes argument is given, fields ' + 'and int need to be None') if len(bytes) != 16: raise ValueError('bytes is not a 16-char string') int = (struct.unpack('>Q', bytes[:8])[0] << 64 | struct.unpack('>Q', bytes[8:])[0]) elif fields is not None: if int is not None: - raise TypeError('if the fields argument is given, int needs to be None') + raise TypeError('if the fields argument is given, int needs' + ' to be None') if len(fields) != 6: raise ValueError('fields is not a 6-tuple') (time_low, time_mid, time_hi_version, diff --git a/pypy/doc/faq.rst b/pypy/doc/faq.rst --- a/pypy/doc/faq.rst +++ b/pypy/doc/faq.rst @@ -356,7 +356,7 @@ attempt to point newcomers at existing alternatives, which are more mainstream and where they will get help from many people.* - *If anybody seriously wants to promote RPython anyway, he is welcome + *If anybody seriously wants to promote RPython anyway, they are welcome to: we won't actively resist such a plan. There are a lot of things that could be done to make RPython a better Java-ish language for example, starting with supporting non-GIL-based multithreading, but we @@ -396,8 +396,8 @@ patch the generated machine code. So the position of the core PyPy developers is that if anyone wants to -make an N+1'th attempt with LLVM, he is welcome, and he will receive a -bit of help on the IRC channel, but he is left with the burden of proof +make an N+1'th attempt with LLVM, they are welcome, and will be happy to +provide help in the IRC channel, but they are left with the burden of proof that it works. ---------------------- 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 @@ -81,6 +81,8 @@ .. branch: numpypy-inplace-op .. branch: rewritten-loop-logging .. branch: no-release-gil +.. branch: safe-win-mmap +.. branch: boolean-indexing-cleanup .. branch: nobold-backtrace Work on improving UnionError messages and stack trace displays. 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 @@ -316,7 +316,8 @@ self.storage = storage def create_iter(self, shape=None, backward_broadcast=False): - if shape is None or shape == self.get_shape(): + if shape is None or \ + support.product(shape) <= support.product(self.get_shape()): return iter.ConcreteArrayIterator(self) r = calculate_broadcast_strides(self.get_strides(), self.get_backstrides(), @@ -385,7 +386,8 @@ loop.fill(self, box.convert_to(self.dtype)) def create_iter(self, shape=None, backward_broadcast=False): - if shape is not None and shape != self.get_shape(): + if shape is not None and shape != self.get_shape() and \ + support.product(shape) > support.product(self.get_shape()): r = calculate_broadcast_strides(self.get_strides(), self.get_backstrides(), self.get_shape(), shape, 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 @@ -88,28 +88,22 @@ w_res = W_NDimArray.from_shape(space, res_shape, self.get_dtype(), w_instance=self) return loop.getitem_filter(w_res, self, arr) - def setitem_filter(self, space, idx, value): - from pypy.module.micronumpy.interp_boxes import Box - val = value + def setitem_filter(self, space, idx, val): if len(idx.get_shape()) > 1 and idx.get_shape() != self.get_shape(): raise OperationError(space.w_ValueError, space.wrap("boolean index array should have 1 dimension")) if idx.get_size() > self.get_size(): raise OperationError(space.w_ValueError, space.wrap("index out of range for array")) - idx_iter = idx.create_iter(self.get_shape()) - size = loop.count_all_true_iter(idx_iter, self.get_shape(), idx.get_dtype()) - if len(val.get_shape()) > 0 and val.get_shape()[0] > 1 and size > val.get_shape()[0]: + idx_iter = idx.create_iter() + size = loop.count_all_true_iter(idx_iter, idx.get_shape(), idx.get_dtype()) + if size > val.get_size() and val.get_size() > 1: raise OperationError(space.w_ValueError, space.wrap("NumPy boolean array indexing assignment " "cannot assign %d input values to " - "the %d output values where the mask is true" % (val.get_shape()[0],size))) - if val.get_shape() == [1]: - box = val.descr_getitem(space, space.wrap(0)) - assert isinstance(box, Box) - val = W_NDimArray(scalar.Scalar(val.get_dtype(), box)) - elif val.get_shape() == [0]: + "the %d output values where the mask is true" % (val.get_size(), size))) + if val.get_shape() == [0]: val.implementation.dtype = self.implementation.dtype - loop.setitem_filter(self, idx, val) + loop.setitem_filter(self, idx, val, size) def _prepare_array_index(self, space, w_index): if isinstance(w_index, W_NDimArray): 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 @@ -372,10 +372,10 @@ 'index_dtype'], reds = 'auto') -def setitem_filter(arr, index, value): +def setitem_filter(arr, index, value, size): arr_iter = arr.create_iter() index_iter = index.create_iter(arr.get_shape()) - value_iter = value.create_iter() + value_iter = value.create_iter([size]) shapelen = len(arr.get_shape()) index_dtype = index.get_dtype() arr_dtype = arr.get_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 @@ -2355,11 +2355,16 @@ def test_array_indexing_bool_specialcases(self): from numpypy import arange, array a = arange(6) - try: - a[a < 3] = [1, 2] - assert False, "Should not work" - except ValueError: - pass + exc = raises(ValueError,'a[a < 3] = [1, 2]') + assert exc.value[0].find('cannot assign') >= 0 + b = arange(4).reshape(2, 2) + 10 + a[a < 4] = b + assert (a == [10, 11, 12, 13, 4, 5]).all() + b += 10 + c = arange(8).reshape(2, 2, 2) + a[a > 9] = c[:, :, 1] + assert (c[:, :, 1] == [[1, 3], [5, 7]]).all() + assert (a == [1, 3, 5, 7, 4, 5]).all() a = arange(6) a[a > 3] = array([15]) assert (a == [0, 1, 2, 3, 15, 15]).all() diff --git a/rpython/rlib/rmmap.py b/rpython/rlib/rmmap.py --- a/rpython/rlib/rmmap.py +++ b/rpython/rlib/rmmap.py @@ -118,10 +118,16 @@ return unsafe, safe def winexternal(name, args, result, **kwargs): - return rffi.llexternal(name, args, result, + unsafe = rffi.llexternal(name, args, result, compilation_info=CConfig._compilation_info_, calling_conv='win', **kwargs) + safe = rffi.llexternal(name, args, result, + compilation_info=CConfig._compilation_info_, + calling_conv='win', + sandboxsafe=True, releasegil=False, + **kwargs) + return unsafe, safe PTR = rffi.CCHARP @@ -188,32 +194,29 @@ SYSTEM_INFO = config['SYSTEM_INFO'] SYSTEM_INFO_P = lltype.Ptr(SYSTEM_INFO) - GetSystemInfo = winexternal('GetSystemInfo', [SYSTEM_INFO_P], lltype.Void) - GetFileSize = winexternal('GetFileSize', [HANDLE, LPDWORD], DWORD) - GetCurrentProcess = winexternal('GetCurrentProcess', [], HANDLE) - DuplicateHandle = winexternal('DuplicateHandle', [HANDLE, HANDLE, HANDLE, LPHANDLE, DWORD, BOOL, DWORD], BOOL) - CreateFileMapping = winexternal('CreateFileMappingA', [HANDLE, rwin32.LPSECURITY_ATTRIBUTES, DWORD, DWORD, DWORD, LPCSTR], HANDLE) - MapViewOfFile = winexternal('MapViewOfFile', [HANDLE, DWORD, DWORD, DWORD, SIZE_T], LPCSTR)##!!LPVOID) - UnmapViewOfFile = winexternal('UnmapViewOfFile', [LPCSTR], BOOL, - releasegil=False) - FlushViewOfFile = winexternal('FlushViewOfFile', [LPCSTR, SIZE_T], BOOL) - SetFilePointer = winexternal('SetFilePointer', [HANDLE, LONG, PLONG, DWORD], DWORD) - SetEndOfFile = winexternal('SetEndOfFile', [HANDLE], BOOL) - VirtualAlloc = winexternal('VirtualAlloc', + GetSystemInfo, _ = winexternal('GetSystemInfo', [SYSTEM_INFO_P], lltype.Void) + GetFileSize, _ = winexternal('GetFileSize', [HANDLE, LPDWORD], DWORD) + GetCurrentProcess, _ = winexternal('GetCurrentProcess', [], HANDLE) + DuplicateHandle, _ = winexternal('DuplicateHandle', [HANDLE, HANDLE, HANDLE, LPHANDLE, DWORD, BOOL, DWORD], BOOL) + CreateFileMapping, _ = winexternal('CreateFileMappingA', [HANDLE, rwin32.LPSECURITY_ATTRIBUTES, DWORD, DWORD, DWORD, LPCSTR], HANDLE) + MapViewOfFile, _ = winexternal('MapViewOfFile', [HANDLE, DWORD, DWORD, DWORD, SIZE_T], LPCSTR)##!!LPVOID) + _, UnmapViewOfFile_safe = winexternal('UnmapViewOfFile', [LPCSTR], BOOL) + FlushViewOfFile, _ = winexternal('FlushViewOfFile', [LPCSTR, SIZE_T], BOOL) + SetFilePointer, _ = winexternal('SetFilePointer', [HANDLE, LONG, PLONG, DWORD], DWORD) + SetEndOfFile, _ = winexternal('SetEndOfFile', [HANDLE], BOOL) + VirtualAlloc, VirtualAlloc_safe = winexternal('VirtualAlloc', [rffi.VOIDP, rffi.SIZE_T, DWORD, DWORD], rffi.VOIDP) - # VirtualProtect is used in llarena and should not release the GIL - _VirtualProtect = winexternal('VirtualProtect', + _, _VirtualProtect_safe = winexternal('VirtualProtect', [rffi.VOIDP, rffi.SIZE_T, DWORD, LPDWORD], - BOOL, - _nowrapper=True) + BOOL) def VirtualProtect(addr, size, mode, oldmode_ptr): - return _VirtualProtect(addr, + return _VirtualProtect_safe(addr, rffi.cast(rffi.SIZE_T, size), rffi.cast(DWORD, mode), oldmode_ptr) VirtualProtect._annspecialcase_ = 'specialize:ll' - VirtualFree = winexternal('VirtualFree', + VirtualFree, VirtualFree_safe = winexternal('VirtualFree', [rffi.VOIDP, rffi.SIZE_T, DWORD], BOOL) def _get_page_size(): @@ -300,7 +303,7 @@ def unmap(self): if _MS_WINDOWS: - UnmapViewOfFile(self.getptr(0)) + UnmapViewOfFile_safe(self.getptr(0)) elif _POSIX: self.unmap_range(0, self.size) @@ -575,6 +578,7 @@ def getitem(self, index): # simplified version, for rpython + self.check_valid() if index < 0: index += self.size return self.data[index] @@ -846,7 +850,7 @@ case of a sandboxed process """ null = lltype.nullptr(rffi.VOIDP.TO) - res = VirtualAlloc(null, map_size, MEM_COMMIT | MEM_RESERVE, + res = VirtualAlloc_safe(null, map_size, MEM_COMMIT | MEM_RESERVE, PAGE_EXECUTE_READWRITE) if not res: raise MemoryError @@ -858,6 +862,6 @@ alloc._annenforceargs_ = (int,) def free(ptr, map_size): - VirtualFree(ptr, 0, MEM_RELEASE) + VirtualFree_safe(ptr, 0, MEM_RELEASE) # register_external here? diff --git a/rpython/rtyper/lltypesystem/llarena.py b/rpython/rtyper/lltypesystem/llarena.py --- a/rpython/rtyper/lltypesystem/llarena.py +++ b/rpython/rtyper/lltypesystem/llarena.py @@ -535,6 +535,7 @@ else: from rpython.rlib.rmmap import PAGE_READWRITE as newprotect arg = lltype.malloc(LPDWORD.TO, 1, zero=True, flavor='raw') + #does not release the GIL VirtualProtect(rffi.cast(rffi.VOIDP, addr), size, newprotect, arg) # ignore potential errors 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 @@ -1668,6 +1668,16 @@ return extdef([int], int, llimpl=nice_llimpl, export_name="ll_os.ll_os_nice") + @registering_if(os, 'ctermid') + def register_os_ctermid(self): + os_ctermid = self.llexternal('ctermid', [rffi.CCHARP], rffi.CCHARP) + + def ctermid_llimpl(): + return rffi.charp2str(os_ctermid(lltype.nullptr(rffi.CCHARP.TO))) + + return extdef([], str, llimpl=ctermid_llimpl, + export_name="ll_os.ll_os_ctermid") + # --------------------------- os.stat & variants --------------------------- @registering(os.fstat) diff --git a/rpython/rtyper/tool/rffi_platform.py b/rpython/rtyper/tool/rffi_platform.py --- a/rpython/rtyper/tool/rffi_platform.py +++ b/rpython/rtyper/tool/rffi_platform.py @@ -844,6 +844,10 @@ library_dir = '' libraries = ['gc64_dll'] includes = ['gc.h'] + # since config_external_library does not use a platform kwarg, + # somehow using a platform kw arg make the merge fail in + # config_external_library + platform = None else: library_dir = '' libraries = ['gc', 'dl'] From noreply at buildbot.pypy.org Wed Sep 18 14:25:10 2013 From: noreply at buildbot.pypy.org (fijal) Date: Wed, 18 Sep 2013 14:25:10 +0200 (CEST) Subject: [pypy-commit] pypy file-support-in-rpython: seek support Message-ID: <20130918122510.0090F1C01B0@cobra.cs.uni-duesseldorf.de> Author: Maciej Fijalkowski Branch: file-support-in-rpython Changeset: r67001:404ed50b9af2 Date: 2013-09-18 13:46 +0200 http://bitbucket.org/pypy/pypy/changeset/404ed50b9af2/ Log: seek support diff --git a/rpython/rlib/rfile.py b/rpython/rlib/rfile.py --- a/rpython/rlib/rfile.py +++ b/rpython/rlib/rfile.py @@ -2,8 +2,10 @@ """ This file makes open() and friends RPython """ +import os from rpython.annotator.model import SomeObject, SomeString, SomeInteger from rpython.rtyper.extregistry import ExtRegistryEntry +from rpython.rtyper.extfunc import register_external class SomeFile(SomeObject): def method_write(self, s_arg): @@ -17,6 +19,11 @@ def method_close(self): pass + def method_seek(self, s_arg, s_whence=None): + assert isinstance(s_arg, SomeInteger) + if s_whence is not None: + assert isinstance(s_whence, SomeInteger) + def rtyper_makekey(self): return self.__class__, @@ -36,3 +43,8 @@ def specialize_call(self, hop): return hop.r_result.rtype_constructor(hop) + + #def ll_os_tmpfile(): + #pass + + #register_external(os.tmpfile, [], SomeFile(), llimpl=ll_os_tmpfile) diff --git a/rpython/rlib/test/test_rfile.py b/rpython/rlib/test/test_rfile.py --- a/rpython/rlib/test/test_rfile.py +++ b/rpython/rlib/test/test_rfile.py @@ -53,3 +53,16 @@ assert e == "" self.interpret(f, []) + + def test_seek(self): + fname = str(self.tmpdir.join('file_4')) + + def f(): + f = open(fname, "w+") + f.write("xxx") + f.seek(0) + assert f.read() == "xxx" + f.close() + + f() + self.interpret(f, []) diff --git a/rpython/rtyper/lltypesystem/rfile.py b/rpython/rtyper/lltypesystem/rfile.py --- a/rpython/rtyper/lltypesystem/rfile.py +++ b/rpython/rtyper/lltypesystem/rfile.py @@ -27,6 +27,8 @@ c_feof = rffi.llexternal('feof', [lltype.Ptr(FILE)], rffi.INT) c_ferror = rffi.llexternal('ferror', [lltype.Ptr(FILE)], rffi.INT) c_clearerror = rffi.llexternal('clearerr', [lltype.Ptr(FILE)], lltype.Void) +c_fseek = rffi.llexternal('fseek', [lltype.Ptr(FILE), rffi.LONG, rffi.INT], + rffi.INT) def ll_open(name, mode): file_wrapper = lltype.malloc(FILE_WRAPPER) @@ -104,6 +106,14 @@ finally: rffi.keep_buffer_alive_until_here(raw_buf, gc_buf) return s +def ll_seek(file_wrapper, pos, whence): + ll_file = file_wrapper.file + if not ll_file: + raise ValueError("I/O operation on closed file") + res = c_fseek(ll_file, pos, whence) + if res == -1: + errno = rposix.get_errno() + raise OSError(errno, os.strerror(errno)) def ll_close(file_wrapper): if file_wrapper.file: @@ -153,3 +163,13 @@ arg_1 = hop.inputarg(lltype.Signed, 1) hop.exception_is_here() return hop.gendirectcall(ll_read, r_self, arg_1) + + def rtype_method_seek(self, hop): + r_self = hop.inputarg(self, 0) + arg_1 = hop.inputarg(lltype.Signed, 1) + if len(hop.args_v) != 3: + arg_2 = hop.inputconst(lltype.Signed, os.SEEK_SET) + else: + arg_2 = hop.inputarg(lltype.Signed, 2) + hop.exception_is_here() + return hop.gendirectcall(ll_seek, r_self, arg_1, arg_2) From noreply at buildbot.pypy.org Wed Sep 18 16:27:08 2013 From: noreply at buildbot.pypy.org (mattip) Date: Wed, 18 Sep 2013 16:27:08 +0200 (CEST) Subject: [pypy-commit] pypy pypy-pyarray: update tasks in TODO Message-ID: <20130918142708.4B89E1C14E1@cobra.cs.uni-duesseldorf.de> Author: Matti Picus Branch: pypy-pyarray Changeset: r67003:6c9c6e373d99 Date: 2013-09-18 17:09 +0300 http://bitbucket.org/pypy/pypy/changeset/6c9c6e373d99/ Log: update tasks in TODO diff --git a/TODO.txt b/TODO.txt --- a/TODO.txt +++ b/TODO.txt @@ -13,7 +13,5 @@ all ndarrayobject.c copy_header_files() in api.py (changed) all ndarrayobject.py (new) - PyNumber_CoerceEx() (new) - PyNumber_Coerce() (new) - test, implement use of __array_prepare__() - test, implement use of __array_wrap__() From noreply at buildbot.pypy.org Wed Sep 18 16:27:07 2013 From: noreply at buildbot.pypy.org (mattip) Date: Wed, 18 Sep 2013 16:27:07 +0200 (CEST) Subject: [pypy-commit] pypy pypy-pyarray: add c test, fix PyNumber_Coerce{, Ex} Message-ID: <20130918142707.20E401C0113@cobra.cs.uni-duesseldorf.de> Author: Matti Picus Branch: pypy-pyarray Changeset: r67002:95c2319fa157 Date: 2013-09-18 17:07 +0300 http://bitbucket.org/pypy/pypy/changeset/95c2319fa157/ Log: add c test, fix PyNumber_Coerce{,Ex} including PyDecRef example code for successful call since coerce returns new object diff --git a/pypy/module/cpyext/api.py b/pypy/module/cpyext/api.py --- a/pypy/module/cpyext/api.py +++ b/pypy/module/cpyext/api.py @@ -338,7 +338,7 @@ return api_function.error_value if not we_are_translated(): got_integer = isinstance(res, (int, long, float)) - assert got_integer == expect_integer + assert got_integer == expect_integer,'got %r not integer' % res if res is None: return None elif isinstance(res, Reference): diff --git a/pypy/module/cpyext/number.py b/pypy/module/cpyext/number.py --- a/pypy/module/cpyext/number.py +++ b/pypy/module/cpyext/number.py @@ -3,6 +3,7 @@ from pypy.module.cpyext.pyobject import PyObject, PyObjectP, from_ref, make_ref, Py_DecRef from rpython.rtyper.lltypesystem import rffi, lltype from rpython.tool.sourcetools import func_with_new_name +from pypy.module.cpyext.state import State @cpython_api([PyObject], rffi.INT_real, error=CANNOT_FAIL) def PyIndex_Check(space, w_obj): @@ -56,24 +57,17 @@ """ return space.index(w_obj) - at cpython_api([PyObjectP, PyObjectP], rffi.INT_real, error=-1) + at cpython_api([PyObjectP, PyObjectP], rffi.INT_real, error=CANNOT_FAIL) def PyNumber_CoerceEx(space, pp1, pp2): """This function is similar to PyNumber_Coerce(), except that it returns 1 when the conversion is not possible and when no error is raised. Reference counts are still not increased in this case.""" - w_obj1 = from_ref(space, pp1[0]) - w_obj2 = from_ref(space, pp2[0]) - w_res = space.try_coerce(w_obj1, w_obj2) - if w_res is None: + retVal = PyNumber_Coerce(space, pp1, pp2) + if retVal != 0: return 1 - else: - Py_DecRef(space, pp1[0]) - Py_DecRef(space, pp2[0]) - pp1[0] = make_ref(space, space.getitem(w_res, space.wrap(0))) - pp2[0] = make_ref(space, space.getitem(w_res, space.wrap(1))) - return 0 + return 0 - at cpython_api([PyObjectP, PyObjectP], rffi.INT_real, error=-1) + at cpython_api([PyObjectP, PyObjectP], rffi.INT_real, error=CANNOT_FAIL) def PyNumber_Coerce(space, pp1, pp2): """This function takes the addresses of two variables of type PyObject*. If the objects pointed to by *p1 and *p2 have the same type, increment their @@ -85,15 +79,16 @@ Python statement o1, o2 = coerce(o1, o2).""" w_obj1 = from_ref(space, pp1[0]) w_obj2 = from_ref(space, pp2[0]) - w_res = space.coerce(w_obj1, w_obj2) - if w_res is None: + try: + w_res = space.coerce(w_obj1, w_obj2) + except (TypeError, OperationError): + state = space.fromcache(State) + state.clear_exception() return -1 - else: - Py_DecRef(space, pp1[0]) - Py_DecRef(space, pp2[0]) - pp1[0] = make_ref(space, space.getitem(w_res, space.wrap(0))) - pp2[0] = make_ref(space, space.getitem(w_res, space.wrap(1))) - return 0 + w_res1, w_res2 = space.unpackiterable(w_res, 2) + pp1[0] = make_ref(space, w_res1) + pp2[0] = make_ref(space, w_res2) + return 0 def func_rename(newname): return lambda func: func_with_new_name(func, newname) diff --git a/pypy/module/cpyext/test/test_number.py b/pypy/module/cpyext/test/test_number.py --- a/pypy/module/cpyext/test/test_number.py +++ b/pypy/module/cpyext/test/test_number.py @@ -1,6 +1,7 @@ from rpython.rtyper.lltypesystem import lltype from pypy.module.cpyext.test.test_api import BaseApiTest from pypy.module.cpyext.pyobject import PyObjectP, from_ref, make_ref, Py_DecRef +from pypy.module.cpyext.test.test_cpyext import AppTestCpythonExtensionBase class TestIterator(BaseApiTest): def test_check(self, space, api): @@ -46,10 +47,10 @@ assert space.str_w(space.repr(from_ref(space, pp2[0]))) == '456.789' Py_DecRef(space, pp1[0]) Py_DecRef(space, pp2[0]) - # Yes, decrement twice. + lltype.free(pp1, flavor='raw') + # Yes, decrement twice since we decoupled between w_obj* and pp*[0]. Py_DecRef(space, w_obj1) Py_DecRef(space, w_obj2) - lltype.free(pp1, flavor='raw') lltype.free(pp2, flavor='raw') def test_number_coerce_ex(self, space, api): @@ -67,6 +68,8 @@ assert api.PyFloat_Check(w_res) assert space.unwrap(w_res) == 123. + Py_DecRef(space, pl) + Py_DecRef(space, pf) Py_DecRef(space, ppl[0]) Py_DecRef(space, ppf[0]) lltype.free(ppl, flavor='raw') @@ -97,3 +100,40 @@ api.PyNumber_Power(space.wrap(3), space.wrap(2), space.wrap(5))) assert 9 == space.unwrap( api.PyNumber_InPlacePower(space.wrap(3), space.wrap(2), space.w_None)) + +class AppTestCNumber(AppTestCpythonExtensionBase): + def test_app_coerce(self): + mod = self.import_extension('foo', [ + ("test_fail", "METH_NOARGS", + ''' + PyObject * hello = PyString_FromString("hello"); + PyObject * float1 = PyFloat_FromDouble(1.0); + int retVal = PyNumber_Coerce(&hello, &float1); + Py_DECREF(hello); + Py_DECREF(float1); + return PyInt_FromLong(retVal); + '''), + ("test", "METH_NOARGS", + ''' + PyObject * float1p = PyFloat_FromDouble(1.0); + PyObject * int3p = PyInt_FromLong(3); + PyObject * tupl = PyTuple_New(2); + PyObject float1 = *float1p; + PyObject int3 = *int3p; + int retVal = PyNumber_CoerceEx(&int3p, &float1p); + if (retVal == 0) + { + PyTuple_SET_ITEM(tupl, 0, int3p); + PyTuple_SET_ITEM(tupl, 1, float1p); + } + Py_DECREF(&int3); + Py_DECREF(&float1); + Py_DECREF(int3p); + Py_DECREF(float1p); + return tupl; + ''')]) + assert mod.test_fail() == -1 + '''tupl = mod.test() + assert tupl[0] == 3. + assert tupl[1] == 1. + assert isinstance(tupl[0], float)''' From noreply at buildbot.pypy.org Wed Sep 18 16:27:09 2013 From: noreply at buildbot.pypy.org (mattip) Date: Wed, 18 Sep 2013 16:27:09 +0200 (CEST) Subject: [pypy-commit] pypy pypy-pyarray: while this review comment is true, it's not that critical Message-ID: <20130918142709.6109B1C0113@cobra.cs.uni-duesseldorf.de> Author: Matti Picus Branch: pypy-pyarray Changeset: r67004:591ef4140c55 Date: 2013-09-18 17:10 +0300 http://bitbucket.org/pypy/pypy/changeset/591ef4140c55/ Log: while this review comment is true, it's not that critical diff --git a/TODO.txt b/TODO.txt --- a/TODO.txt +++ b/TODO.txt @@ -1,9 +1,6 @@ Comments by antocuni, rguillebert ================================== -- why do we need to implement array.nonzero on this branch and it was not done - e.g. on default? - TODO list by mattip =================== From noreply at buildbot.pypy.org Thu Sep 19 01:57:43 2013 From: noreply at buildbot.pypy.org (pjenvey) Date: Thu, 19 Sep 2013 01:57:43 +0200 (CEST) Subject: [pypy-commit] pypy remove-intlong-smm: beginnings of int/bool multimethod removal Message-ID: <20130918235744.16C8B1C0113@cobra.cs.uni-duesseldorf.de> Author: Philip Jenvey Branch: remove-intlong-smm Changeset: r67005:c67fd8fbc7f3 Date: 2013-09-18 16:56 -0700 http://bitbucket.org/pypy/pypy/changeset/c67fd8fbc7f3/ Log: beginnings of int/bool multimethod removal 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 @@ -5,7 +5,7 @@ from pypy.objspace.std.floattype import float_typedef from pypy.objspace.std.stringtype import str_typedef from pypy.objspace.std.unicodetype import unicode_typedef, unicode_from_object -from pypy.objspace.std.inttype import int_typedef +from pypy.objspace.std.intobject import W_IntObject from pypy.objspace.std.complextype import complex_typedef from rpython.rlib.rarithmetic import LONG_BIT from rpython.rtyper.lltypesystem import rffi @@ -17,8 +17,8 @@ from rpython.rlib.rstring import StringBuilder -MIXIN_32 = (int_typedef,) if LONG_BIT == 32 else () -MIXIN_64 = (int_typedef,) if LONG_BIT == 64 else () +MIXIN_32 = (W_IntObject.typedef,) if LONG_BIT == 32 else () +MIXIN_64 = (W_IntObject.typedef,) if LONG_BIT == 64 else () # Is this the proper place for this? ENABLED_LONG_DOUBLE = False 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 @@ -1,14 +1,13 @@ +from rpython.rlib.rarithmetic import r_uint from rpython.rlib.rbigint import rbigint -from rpython.rlib.rarithmetic import r_uint -from pypy.interpreter.error import OperationError -from pypy.objspace.std import newformat -from pypy.objspace.std.model import registerimplementation, W_Object -from pypy.objspace.std.register_all import register_all -from pypy.objspace.std.intobject import W_IntObject +from pypy.interpreter.gateway import WrappedDefault, interp2app, unwrap_spec +from pypy.objspace.std.intobject import W_AbstractIntObject, W_IntObject +from pypy.objspace.std.stdtypedef import StdTypeDef -class W_BoolObject(W_Object): - from pypy.objspace.std.booltype import bool_typedef as typedef + +class W_BoolObject(W_AbstractIntObject): + _immutable_fields_ = ['boolval'] def __init__(self, boolval): @@ -40,40 +39,48 @@ def int(self, space): return space.newint(int(self.boolval)) -registerimplementation(W_BoolObject) + def descr_repr(self, space): + return space.wrap('True' if self.boolval else 'False') + + descr_str = descr_repr + + def descr_nonzero(self, space): + return self + + def descr_and(self, space, w_other): + if not isinstance(w_other, W_BoolObject): + return W_AbstractIntObject.descr_and(self, space, w_other) + return space.newbool(self.boolval & w_other.boolval) + + def descr_or(self, space, w_other): + if not isinstance(w_other, W_BoolObject): + return W_AbstractIntObject.descr_or(self, space, w_other) + return space.newbool(self.boolval | w_other.boolval) + + def descr_xor(self, space, w_other): + if not isinstance(w_other, W_BoolObject): + return W_AbstractIntObject.descr_xor(self, space, w_other) + return space.newbool(self.boolval ^ w_other.boolval) W_BoolObject.w_False = W_BoolObject(False) W_BoolObject.w_True = W_BoolObject(True) -# bool-to-int delegation requires translating the .boolvar attribute -# to an .intval one -def delegate_Bool2IntObject(space, w_bool): - return W_IntObject(int(w_bool.boolval)) + at unwrap_spec(w_obj=WrappedDefault(False)) +def descr__new__(space, w_booltype, w_obj): + space.w_bool.check_user_subclass(w_booltype) + return space.newbool(space.is_true(w_obj)) # XXX: method call? +# ____________________________________________________________ -def nonzero__Bool(space, w_bool): - return w_bool +W_BoolObject.typedef = StdTypeDef("bool", W_IntObject.typedef, + __doc__ = """bool(x) -> bool -def repr__Bool(space, w_bool): - if w_bool.boolval: - return space.wrap('True') - else: - return space.wrap('False') - -def and__Bool_Bool(space, w_bool1, w_bool2): - return space.newbool(w_bool1.boolval & w_bool2.boolval) - -def or__Bool_Bool(space, w_bool1, w_bool2): - return space.newbool(w_bool1.boolval | w_bool2.boolval) - -def xor__Bool_Bool(space, w_bool1, w_bool2): - return space.newbool(w_bool1.boolval ^ w_bool2.boolval) - -str__Bool = repr__Bool - -def format__Bool_ANY(space, w_bool, w_format_spec): - return newformat.run_formatter( - space, w_format_spec, "format_int_or_long", w_bool, - newformat.INT_KIND) - -register_all(vars()) +Returns True when the argument x is true, False otherwise. +The builtins True and False are the only two instances of the class bool. +The class bool is a subclass of the class int, and cannot be subclassed.""", + __new__ = interp2app(descr__new__), + __repr__ = interp2app(W_BoolObject.descr_repr), + __str__ = interp2app(W_BoolObject.descr_str), + # XXX: might as well declare interp2app directly here for nonzero/and/etc + ) +W_BoolObject.typedef.acceptable_as_base_class = False diff --git a/pypy/objspace/std/booltype.py b/pypy/objspace/std/booltype.py deleted file mode 100644 --- a/pypy/objspace/std/booltype.py +++ /dev/null @@ -1,23 +0,0 @@ -from pypy.interpreter.gateway import interp2app, unwrap_spec, WrappedDefault -from pypy.objspace.std.stdtypedef import StdTypeDef -from pypy.objspace.std.inttype import int_typedef - - at unwrap_spec(w_obj = WrappedDefault(False)) -def descr__new__(space, w_booltype, w_obj): - space.w_bool.check_user_subclass(w_booltype) - if space.is_true(w_obj): - return space.w_True - else: - return space.w_False - -# ____________________________________________________________ - -bool_typedef = StdTypeDef("bool", int_typedef, - __doc__ = '''bool(x) -> bool - -Returns True when the argument x is true, False otherwise. -The builtins True and False are the only two instances of the class bool. -The class bool is a subclass of the class int, and cannot be subclassed.''', - __new__ = interp2app(descr__new__), - ) -bool_typedef.acceptable_as_base_class = 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 @@ -28,9 +28,8 @@ w_1 = f.popvalue() if (type(w_1) is intobject.W_IntObject and type(w_2) is intobject.W_IntObject): - try: - w_result = intobject.add__Int_Int(f.space, w_1, w_2) - except FailedToImplement: + w_result = w_1.descr_add(f.space, w_2) + if f.space.is_w(w_result, f.space.w_NotImplemented): w_result = f.space.add(w_1, w_2) else: w_result = f.space.add(w_1, w_2) 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 @@ -6,24 +6,342 @@ """ from rpython.rlib import jit -from rpython.rlib.rarithmetic import LONG_BIT, is_valid_int, ovfcheck, r_uint +from rpython.rlib.rarithmetic import ( + LONG_BIT, is_valid_int, ovfcheck, string_to_int, r_uint) from rpython.rlib.rbigint import rbigint +from rpython.rlib.objectmodel import instantiate +from rpython.rlib.rstring import ParseStringError, ParseStringOverflowError +from rpython.tool.sourcetools import func_with_new_name -from pypy.interpreter.error import OperationError +from pypy.interpreter import typedef +from pypy.interpreter.buffer import Buffer +from pypy.interpreter.error import OperationError, operationerrfmt +from pypy.interpreter.gateway import ( + WrappedDefault, interp2app, interpindirect2app, unwrap_spec) from pypy.objspace.std import newformat -from pypy.objspace.std.inttype import W_AbstractIntObject -from pypy.objspace.std.model import W_Object, registerimplementation -from pypy.objspace.std.multimethod import FailedToImplementArgs -from pypy.objspace.std.noneobject import W_NoneObject -from pypy.objspace.std.register_all import register_all +from pypy.objspace.std.model import W_Object +from pypy.objspace.std.stdtypedef import StdTypeDef + + +class W_AbstractIntObject(W_Object): + __slots__ = () + + def int(self, space): + raise NotImplementedError + + def descr_format(self, space, w_format_spec): + return newformat.run_formatter(space, w_format_spec, + "format_int_or_long", self, + newformat.INT_KIND) + + def descr_hash(self, space): + # 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 self.int(space) + + def descr_coerce(self, space, w_other): + if not space.isinstance_w(w_other, space.w_int): + return space.w_NotImplemented + # XXX: have to call space.int on w_other: 2 + # .__coerce__(True) -> (2, 1): actually cpython doesn't do + # this, so i don't care! + return space.newtuple([self, w_other]) + + def _make_descr_binop(opname): + # XXX: func_renamer or func_with_new_name? + import operator + from rpython.tool.sourcetools import func_renamer + op = getattr(operator, opname) + + @func_renamer('descr_' + opname) + def descr_binop(self, space, w_other): + if not space.isinstance_w(w_other, space.w_int): + return space.w_NotImplemented + + x = space.int_w(self) + y = space.int_w(w_other) + try: + z = ovfcheck(op(x, y)) + except OverflowError: + w_long1 = _delegate_Int2Long(space, self) + # XXX: this needs to be _delegate_Int2Long(space, + # space.int(w_other)) to support bools. so maybe delegation + # should work against space.int_w(w_other) + w_long2 = _delegate_Int2Long(space, w_other) + return getattr(space, opname)(w_long1, w_long2) + return wrapint(space, z) + + @func_renamer('descr_r' + opname) + def descr_rbinop(self, space, w_other): + if not space.isinstance_w(w_other, space.w_int): + return space.w_NotImplemented + + x = space.int_w(self) + y = space.int_w(w_other) + try: + z = ovfcheck(op(y, x)) + except OverflowError: + w_long1 = _delegate_Int2Long(space, self) + # XXX: this needs to be _delegate_Int2Long(space, + # space.int(w_other)) to support bools. so maybe delegation + # should work against space.int_w(w_other) + w_long2 = _delegate_Int2Long(space, w_other) + return getattr(space, opname)(w_long2, w_long1) + return wrapint(space, z) + + return descr_binop, descr_rbinop + + descr_add, descr_radd = _make_descr_binop('add') + descr_sub, descr_rsub = _make_descr_binop('sub') + descr_mul, descr_rmul = _make_descr_binop('mul') + + def _make_descr_cmp(opname): + import operator + op = getattr(operator, opname) + def f(self, space, w_other): + if not space.isinstance_w(w_other, space.w_int): + return space.w_NotImplemented + + i = space.int_w(self) + j = space.int_w(w_other) + return space.newbool(op(i, j)) + return func_with_new_name(f, "descr_" + opname) + + descr_lt = _make_descr_cmp('lt') + descr_le = _make_descr_cmp('le') + descr_eq = _make_descr_cmp('eq') + descr_ne = _make_descr_cmp('ne') + descr_gt = _make_descr_cmp('gt') + descr_ge = _make_descr_cmp('ge') + + def descr_floordiv(self, space, w_other): + if not space.isinstance_w(w_other, space.w_int): + return space.w_NotImplemented + + x = space.int_w(self) + y = space.int_w(w_other) + try: + z = ovfcheck(x // y) + except ZeroDivisionError: + raise operationerrfmt(space.w_ZeroDivisionError, + "integer division by zero") + except OverflowError: + w_long1 = _delegate_Int2Long(space, self) + w_long2 = _delegate_Int2Long(space, w_other) + return space.floordiv(w_long1, w_long2) + return wrapint(space, z) + + descr_div = func_with_new_name(descr_floordiv, 'descr_div') + + def descr_truediv(self, space, w_other): + if not space.isinstance_w(w_other, space.w_int): + return space.w_NotImplemented + + x = float(space.int_w(self)) + y = float(space.int_w(w_other)) + if y == 0.0: + raise operationerrfmt(space.w_ZeroDivisionError, + "division by zero") + return space.wrap(x / y) + + def descr_mod(self, space, w_other): + if not space.isinstance_w(w_other, space.w_int): + return space.w_NotImplemented + + x = space.int_w(self) + y = space.int_w(w_other) + try: + z = ovfcheck(x % y) + except ZeroDivisionError: + raise operationerrfmt(space.w_ZeroDivisionError, + "integer modulo by zero") + except OverflowError: + w_long1 = _delegate_Int2Long(space, self) + w_long2 = _delegate_Int2Long(space, w_other) + return space.mod(w_long1, w_long2) + return wrapint(space, z) + + def descr_divmod(self, space, w_other): + if not space.isinstance_w(w_other, space.w_int): + return space.w_NotImplemented + + x = space.int_w(self) + y = space.int_w(w_other) + try: + z = ovfcheck(x // y) + except ZeroDivisionError: + raise operationerrfmt(space.w_ZeroDivisionError, + "integer divmod by zero") + except OverflowError: + w_long1 = _delegate_Int2Long(space, self) + w_long2 = _delegate_Int2Long(space, w_other) + return space.divmod(w_long1, w_long2) + + # no overflow possible + m = x % y + w = space.wrap + return space.newtuple([w(z), w(m)]) + + @unwrap_spec(w_modulus=WrappedDefault(None)) + def descr_pow(self, space, w_exponent, w_modulus): + if not space.isinstance_w(w_exponent, space.w_int): + return space.w_NotImplemented + if space.is_none(w_modulus): + z = 0 + elif space.isinstance_w(w_modulus, space.w_int): + # XXX: handle long... overflow? + z = space.int_w(w_modulus) + if z == 0: + raise operationerrfmt(space.w_ValueError, + "pow() 3rd argument cannot be 0") + else: + return self._delegate2longpow(space, w_exponent, w_modulus) + #return space.w_NotImplemented + + x = space.int_w(self) + y = space.int_w(w_exponent) + try: + return space.wrap(_pow_impl(space, x, y, z)) + except NotImplementedError: + return self._delegate2longpow(space, w_exponent, w_modulus) + + def _delegate2longpow(self, space, w_exponent, w_modulus): + # XXX: gross + w_long1 = _delegate_Int2Long(space, self) + w_exponent = _delegate_Int2Long(space, w_exponent) + if not space.is_none(w_modulus): + w_modulus = _delegate_Int2Long(space, w_modulus) + return space.pow(w_long1, w_exponent, w_modulus) + + @unwrap_spec(w_modulus=WrappedDefault(None)) + def descr_rpow(self, space, w_base, w_modulus): + if not space.isinstance_w(w_base, space.w_int): + return space.w_NotImplemented + # XXX: this seems like trouble? + return space.pow(w_base, self, w_modulus) + + def descr_neg(self, space): + a = space.int_w(self) + try: + x = ovfcheck(-a) + except OverflowError: + w_long1 = _delegate_Int2Long(space, self) + return space.neg(w_long1) + return wrapint(space, x) + + def descr_abs(self, space): + return self.int(space) if space.int_w(self) >= 0 else self.descr_neg(space) + + def descr_nonzero(self, space): + return space.newbool(space.int_w(self) != 0) + + def descr_invert(self, space): + return wrapint(space, ~space.int_w(self)) + + def descr_lshift(self, space, w_other): + if not space.isinstance_w(w_other, space.w_int): + return space.w_NotImplemented + + a = space.int_w(self) + b = space.int_w(w_other) + if r_uint(b) < LONG_BIT: # 0 <= b < LONG_BIT + try: + c = ovfcheck(a << b) + except OverflowError: + w_long1 = _delegate_Int2Long(space, self) + w_long2 = _delegate_Int2Long(space, w_other) + return space.lshift(w_long1, w_long2) + return wrapint(space, c) + if b < 0: + raise operationerrfmt(space.w_ValueError, "negative shift count") + else: # b >= LONG_BIT + if a == 0: + return self.int(space) + w_long1 = _delegate_Int2Long(space, self) + w_long2 = _delegate_Int2Long(space, w_other) + return space.lshift(w_long1, w_long2) + + def descr_rshift(self, space, w_other): + if not space.isinstance_w(w_other, space.w_int): + return space.w_NotImplemented + + a = space.int_w(self) + b = space.int_w(w_other) + if r_uint(b) >= LONG_BIT: # not (0 <= b < LONG_BIT) + if b < 0: + raise operationerrfmt(space.w_ValueError, + "negative shift count") + else: # b >= LONG_BIT + if a == 0: + return self.int(space) + if a < 0: + a = -1 + else: + a = 0 + else: + a = a >> b + return wrapint(space, a) + + def descr_and(self, space, w_other): + if not space.isinstance_w(w_other, space.w_int): + return space.w_NotImplemented + + a = space.int_w(self) + b = space.int_w(w_other) + res = a & b + return wrapint(space, res) + + def descr_or(self, space, w_other): + if not space.isinstance_w(w_other, space.w_int): + return space.w_NotImplemented + + a = space.int_w(self) + b = space.int_w(w_other) + res = a | b + return wrapint(space, res) + + def descr_xor(self, space, w_other): + if not space.isinstance_w(w_other, space.w_int): + return space.w_NotImplemented + + a = space.int_w(self) + b = space.int_w(w_other) + res = a ^ b + return wrapint(space, res) + + descr_rand = func_with_new_name(descr_and, 'descr_rand') + descr_ror = func_with_new_name(descr_or, 'descr_ror') + descr_rxor = func_with_new_name(descr_xor, 'descr_rxor') + + def descr_pos(self, space): + return self.int(space) + + descr_trunc = func_with_new_name(descr_pos, 'descr_trunc') + + def descr_index(self, space): + return self.int(space) + + def descr_float(self, space): + a = space.int_w(self) + x = float(a) + return space.newfloat(x) + + def descr_oct(self, space): + return space.wrap(oct(space.int_w(self))) + + def descr_hex(self, space): + return space.wrap(hex(space.int_w(self))) + + def descr_getnewargs(self, space): + return space.newtuple([wrapint(space, space.int_w(self))]) class W_IntObject(W_AbstractIntObject): __slots__ = 'intval' _immutable_fields_ = ['intval'] - from pypy.objspace.std.inttype import int_typedef as typedef - def __init__(self, intval): assert is_valid_int(intval) self.intval = intval @@ -32,6 +350,21 @@ """representation for debugging purposes""" return "%s(%d)" % (self.__class__.__name__, self.intval) + 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 unwrap(self, space): return int(self.intval) int_w = unwrap @@ -60,139 +393,28 @@ a = self.intval return space.newint(a) -registerimplementation(W_IntObject) + def descr_repr(self, space): + res = str(self.intval) + return space.wrap(res) -def repr__Int(space, w_int1): - a = w_int1.intval - res = str(a) - return space.wrap(res) + descr_str = func_with_new_name(descr_repr, 'descr_str') -str__Int = repr__Int - -def format__Int_ANY(space, w_int, w_format_spec): - return newformat.run_formatter(space, w_format_spec, "format_int_or_long", - w_int, newformat.INT_KIND) - -def declare_new_int_comparison(opname): - import operator - from rpython.tool.sourcetools import func_with_new_name - op = getattr(operator, opname) - def f(space, w_int1, w_int2): - i = w_int1.intval - j = w_int2.intval - return space.newbool(op(i, j)) - name = "%s__Int_Int" % (opname,) - return func_with_new_name(f, name), name - -for op in ['lt', 'le', 'eq', 'ne', 'gt', 'ge']: - func, name = declare_new_int_comparison(op) - globals()[name] = func - -def hash__Int(space, w_int1): - # 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 w_int1.int(space) - -# coerce -def coerce__Int_Int(space, w_int1, w_int2): - return space.newtuple([w_int1, w_int2]) - - -def add__Int_Int(space, w_int1, w_int2): - x = w_int1.intval - y = w_int2.intval - try: - z = ovfcheck(x + y) - except OverflowError: - raise FailedToImplementArgs(space.w_OverflowError, - space.wrap("integer addition")) - return space.newint(z) - -def sub__Int_Int(space, w_int1, w_int2): - x = w_int1.intval - y = w_int2.intval - try: - z = ovfcheck(x - y) - except OverflowError: - raise FailedToImplementArgs(space.w_OverflowError, - space.wrap("integer substraction")) - return space.newint(z) - -def mul__Int_Int(space, w_int1, w_int2): - x = w_int1.intval - y = w_int2.intval - try: - z = ovfcheck(x * y) - except OverflowError: - raise FailedToImplementArgs(space.w_OverflowError, - space.wrap("integer multiplication")) - return space.newint(z) - -def floordiv__Int_Int(space, w_int1, w_int2): - x = w_int1.intval - y = w_int2.intval - try: - z = ovfcheck(x // y) - except ZeroDivisionError: - raise OperationError(space.w_ZeroDivisionError, - space.wrap("integer division by zero")) - except OverflowError: - raise FailedToImplementArgs(space.w_OverflowError, - space.wrap("integer division")) - return space.newint(z) -div__Int_Int = floordiv__Int_Int - -def truediv__Int_Int(space, w_int1, w_int2): - x = float(w_int1.intval) - y = float(w_int2.intval) - if y == 0.0: - raise FailedToImplementArgs(space.w_ZeroDivisionError, - space.wrap("float division")) - return space.wrap(x / y) - -def mod__Int_Int(space, w_int1, w_int2): - x = w_int1.intval - y = w_int2.intval - try: - z = ovfcheck(x % y) - except ZeroDivisionError: - raise OperationError(space.w_ZeroDivisionError, - space.wrap("integer modulo by zero")) - except OverflowError: - raise FailedToImplementArgs(space.w_OverflowError, - space.wrap("integer modulo")) - return space.newint(z) - -def divmod__Int_Int(space, w_int1, w_int2): - x = w_int1.intval - y = w_int2.intval - try: - z = ovfcheck(x // y) - except ZeroDivisionError: - raise OperationError(space.w_ZeroDivisionError, - space.wrap("integer divmod by zero")) - except OverflowError: - raise FailedToImplementArgs(space.w_OverflowError, - space.wrap("integer modulo")) - # no overflow possible - m = x % y - w = space.wrap - return space.newtuple([w(z), w(m)]) +def _delegate_Int2Long(space, w_intobj): + from pypy.objspace.std.longobject import W_LongObject + return W_LongObject.fromint(space, w_intobj.int_w(space)) # helper for pow() @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): +def _pow_impl(space, iv, iw, iz): if iw < 0: if iz != 0: - raise OperationError(space.w_TypeError, - space.wrap("pow() 2nd argument " - "cannot be negative when 3rd argument specified")) + msg = ("pow() 2nd argument cannot be negative when 3rd argument " + "specified") + raise operationerrfmt(space.w_TypeError, msg) ## bounce it, since it always returns float - raise FailedToImplementArgs(space.w_ValueError, - space.wrap("integer exponentiation")) + raise NotImplementedError temp = iv ix = 1 try: @@ -210,124 +432,242 @@ if iz: ix = ix % iz except OverflowError: - raise FailedToImplementArgs(space.w_OverflowError, - space.wrap("integer exponentiation")) + raise NotImplementedError return ix -def pow__Int_Int_Int(space, w_int1, w_int2, w_int3): - x = w_int1.intval - y = w_int2.intval - z = w_int3.intval - if z == 0: +# ____________________________________________________________ + +def descr_conjugate(space, w_int): + "Returns self, the complex conjugate of any int." + return space.int(w_int) + +def descr_bit_length(space, w_int): + """int.bit_length() -> int + + Number of bits necessary to represent self in binary. + >>> bin(37) + '0b100101' + >>> (37).bit_length() + 6 + """ + val = space.int_w(w_int) + if val < 0: + val = -val + bits = 0 + while val: + bits += 1 + val >>= 1 + return space.wrap(bits) + + +def wrapint(space, x): + 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 + # use r_uint to perform a single comparison (this whole function + # is getting inlined into every caller so keeping the branching + # to a minimum is a good idea) + index = r_uint(x - lower) + if index >= r_uint(upper - lower): + w_res = instantiate(W_IntObject) + else: + w_res = W_IntObject.PREBUILT[index] + # obscure hack to help the CPU cache: we store 'x' even into + # a prebuilt integer's intval. This makes sure that the intval + # field is present in the cache in the common case where it is + # quickly reused. (we could use a prefetch hint if we had that) + w_res.intval = x + return w_res + else: + from pypy.objspace.std.intobject import W_IntObject + return W_IntObject(x) + +# ____________________________________________________________ + + at jit.elidable +def string_to_int_or_long(space, string, base=10): + w_longval = None + value = 0 + try: + value = string_to_int(string, base) + except ParseStringError, e: raise OperationError(space.w_ValueError, - space.wrap("pow() 3rd argument cannot be 0")) - return space.wrap(_impl_int_int_pow(space, x, y, z)) + space.wrap(e.msg)) + except ParseStringOverflowError, e: + w_longval = retry_to_w_long(space, e.parser) + return value, w_longval -def pow__Int_Int_None(space, w_int1, w_int2, w_int3): - x = w_int1.intval - y = w_int2.intval - return space.wrap(_impl_int_int_pow(space, x, y, 0)) +def retry_to_w_long(space, parser): + parser.rewind() + try: + bigint = rbigint._from_numberstring_parser(parser) + except ParseStringError, e: + raise OperationError(space.w_ValueError, + space.wrap(e.msg)) + return space.newlong_from_rbigint(bigint) -def neg__Int(space, w_int1): - a = w_int1.intval - try: - x = ovfcheck(-a) - except OverflowError: - raise FailedToImplementArgs(space.w_OverflowError, - space.wrap("integer negation")) - return space.newint(x) -get_negint = neg__Int + at unwrap_spec(w_x = WrappedDefault(0)) +def descr__new__(space, w_inttype, w_x, w_base=None): + from pypy.objspace.std.intobject import W_IntObject + w_longval = None + w_value = w_x # 'x' is the keyword argument name in CPython + value = 0 + if w_base is None: + ok = False + # check for easy cases + if type(w_value) is W_IntObject: + value = w_value.intval + ok = True + elif space.isinstance_w(w_value, space.w_str): + value, w_longval = string_to_int_or_long(space, space.str_w(w_value)) + ok = True + elif space.isinstance_w(w_value, space.w_unicode): + from pypy.objspace.std.unicodeobject import unicode_to_decimal_w + string = unicode_to_decimal_w(space, w_value) + value, w_longval = string_to_int_or_long(space, string) + ok = True + else: + # If object supports the buffer interface + try: + w_buffer = space.buffer(w_value) + except OperationError, e: + if not e.match(space, space.w_TypeError): + raise + else: + buf = space.interp_w(Buffer, w_buffer) + value, w_longval = string_to_int_or_long(space, buf.as_str()) + ok = True + if not ok: + # otherwise, use the __int__() or the __trunc__() methods + w_obj = w_value + if space.lookup(w_obj, '__int__') is None: + w_obj = space.trunc(w_obj) + w_obj = space.int(w_obj) + # 'int(x)' should return what x.__int__() returned, which should + # be an int or long or a subclass thereof. + if space.is_w(w_inttype, space.w_int): + return w_obj + # int_w is effectively what we want in this case, + # we cannot construct a subclass of int instance with an + # an overflowing long + try: + value = space.int_w(w_obj) + except OperationError, e: + if e.match(space, space.w_TypeError): + raise OperationError(space.w_ValueError, + space.wrap("value can't be converted to int")) + raise e + else: + base = space.int_w(w_base) -def abs__Int(space, w_int1): - if w_int1.intval >= 0: - return w_int1.int(space) + if space.isinstance_w(w_value, space.w_unicode): + from pypy.objspace.std.unicodeobject import unicode_to_decimal_w + s = unicode_to_decimal_w(space, w_value) + else: + try: + s = space.str_w(w_value) + except OperationError, e: + raise OperationError(space.w_TypeError, + space.wrap("int() can't convert non-string " + "with explicit base")) + + value, w_longval = string_to_int_or_long(space, s, base) + + if w_longval is not None: + if not space.is_w(w_inttype, space.w_int): + raise OperationError(space.w_OverflowError, + space.wrap( + "long int too large to convert to int")) + return w_longval + elif space.is_w(w_inttype, space.w_int): + # common case + return wrapint(space, value) else: - return get_negint(space, w_int1) + w_obj = space.allocate_instance(W_IntObject, w_inttype) + W_IntObject.__init__(w_obj, value) + return w_obj -def nonzero__Int(space, w_int1): - return space.newbool(w_int1.intval != 0) +def descr_get_numerator(space, w_obj): + return space.int(w_obj) -def invert__Int(space, w_int1): - x = w_int1.intval - a = ~x - return space.newint(a) +def descr_get_denominator(space, w_obj): + return space.wrap(1) -def lshift__Int_Int(space, w_int1, w_int2): - a = w_int1.intval - b = w_int2.intval - if r_uint(b) < LONG_BIT: # 0 <= b < LONG_BIT - try: - c = ovfcheck(a << b) - except OverflowError: - raise FailedToImplementArgs(space.w_OverflowError, - space.wrap("integer left shift")) - return space.newint(c) - if b < 0: - raise OperationError(space.w_ValueError, - space.wrap("negative shift count")) - else: #b >= LONG_BIT - if a == 0: - return w_int1.int(space) - raise FailedToImplementArgs(space.w_OverflowError, - space.wrap("integer left shift")) +def descr_get_real(space, w_obj): + return space.int(w_obj) -def rshift__Int_Int(space, w_int1, w_int2): - a = w_int1.intval - b = w_int2.intval - if r_uint(b) >= LONG_BIT: # not (0 <= b < LONG_BIT) - if b < 0: - raise OperationError(space.w_ValueError, - space.wrap("negative shift count")) - else: # b >= LONG_BIT - if a == 0: - return w_int1.int(space) - if a < 0: - a = -1 - else: - a = 0 - else: - a = a >> b - return space.newint(a) +def descr_get_imag(space, w_obj): + return space.wrap(0) -def and__Int_Int(space, w_int1, w_int2): - a = w_int1.intval - b = w_int2.intval - res = a & b - return space.newint(res) +# ____________________________________________________________ -def xor__Int_Int(space, w_int1, w_int2): - a = w_int1.intval - b = w_int2.intval - res = a ^ b - return space.newint(res) -def or__Int_Int(space, w_int1, w_int2): - a = w_int1.intval - b = w_int2.intval - res = a | b - return space.newint(res) +W_IntObject.typedef = StdTypeDef("int", + __doc__ = '''int(x[, base]) -> integer -def pos__Int(self, space): - return self.int(space) -trunc__Int = pos__Int +Convert a string or number to an integer, if possible. A floating point +argument will be truncated towards zero (this does not include a string +representation of a floating point number!) When converting a string, use +the optional base. It is an error to supply a base when converting a +non-string. If the argument is outside the integer range a long object +will be returned instead.''', + __new__ = interp2app(descr__new__), -def index__Int(space, w_int1): - return w_int1.int(space) + conjugate = interp2app(descr_conjugate), + bit_length = interp2app(descr_bit_length), + numerator = typedef.GetSetProperty(descr_get_numerator), + denominator = typedef.GetSetProperty(descr_get_denominator), + real = typedef.GetSetProperty(descr_get_real), + imag = typedef.GetSetProperty(descr_get_imag), + __int__ = interpindirect2app(W_AbstractIntObject.int), -def float__Int(space, w_int1): - a = w_int1.intval - x = float(a) - return space.newfloat(x) + __format__ = interpindirect2app(W_AbstractIntObject.descr_format), + __hash__ = interpindirect2app(W_AbstractIntObject.descr_hash), + __coerce__ = interpindirect2app(W_AbstractIntObject.descr_coerce), -def oct__Int(space, w_int1): - return space.wrap(oct(w_int1.intval)) + __add__ = interpindirect2app(W_AbstractIntObject.descr_add), + __radd__ = interpindirect2app(W_AbstractIntObject.descr_radd), + __sub__ = interpindirect2app(W_AbstractIntObject.descr_sub), + __rsub__ = interpindirect2app(W_AbstractIntObject.descr_rsub), + __mul__ = interpindirect2app(W_AbstractIntObject.descr_mul), + __rmul__ = interpindirect2app(W_AbstractIntObject.descr_rmul), + __lt__ = interpindirect2app(W_AbstractIntObject.descr_lt), + __le__ = interpindirect2app(W_AbstractIntObject.descr_le), + __eq__ = interpindirect2app(W_AbstractIntObject.descr_eq), + __ne__ = interpindirect2app(W_AbstractIntObject.descr_ne), + __gt__ = interpindirect2app(W_AbstractIntObject.descr_gt), + __ge__ = interpindirect2app(W_AbstractIntObject.descr_ge), -def hex__Int(space, w_int1): - return space.wrap(hex(w_int1.intval)) + __floordiv__ = interpindirect2app(W_AbstractIntObject.descr_floordiv), + __div__ = interpindirect2app(W_AbstractIntObject.descr_div), + __truediv__ = interpindirect2app(W_AbstractIntObject.descr_truediv), + __mod__ = interpindirect2app(W_AbstractIntObject.descr_mod), + __divmod__ = interpindirect2app(W_AbstractIntObject.descr_divmod), -def getnewargs__Int(space, w_int1): - return space.newtuple([space.newint(w_int1.intval)]) + __pow__ = interpindirect2app(W_AbstractIntObject.descr_pow), + __rpow__ = interpindirect2app(W_AbstractIntObject.descr_rpow), + __neg__ = interpindirect2app(W_AbstractIntObject.descr_neg), + __abs__ = interpindirect2app(W_AbstractIntObject.descr_abs), + __nonzero__ = interpindirect2app(W_AbstractIntObject.descr_nonzero), + __invert__ = interpindirect2app(W_AbstractIntObject.descr_invert), + __lshift__ = interpindirect2app(W_AbstractIntObject.descr_lshift), + __rshift__ = interpindirect2app(W_AbstractIntObject.descr_rshift), + __and__ = interpindirect2app(W_AbstractIntObject.descr_and), + __rand__ = interpindirect2app(W_AbstractIntObject.descr_rand), + __xor__ = interpindirect2app(W_AbstractIntObject.descr_xor), + __rxor__ = interpindirect2app(W_AbstractIntObject.descr_rxor), + __or__ = interpindirect2app(W_AbstractIntObject.descr_or), + __ror__ = interpindirect2app(W_AbstractIntObject.descr_ror), + __pos__ = interpindirect2app(W_AbstractIntObject.descr_pos), + __trunc__ = interpindirect2app(W_AbstractIntObject.descr_trunc), + __index__ = interpindirect2app(W_AbstractIntObject.descr_index), + __float__ = interpindirect2app(W_AbstractIntObject.descr_float), + __oct__ = interpindirect2app(W_AbstractIntObject.descr_oct), + __hex__ = interpindirect2app(W_AbstractIntObject.descr_hex), + __getnewargs__ = interpindirect2app(W_AbstractIntObject.descr_getnewargs), - -register_all(vars()) + __repr__ = interp2app(W_IntObject.descr_repr), + __str__ = interp2app(W_IntObject.descr_str), +) diff --git a/pypy/objspace/std/inttype.py b/pypy/objspace/std/inttype.py deleted file mode 100644 --- a/pypy/objspace/std/inttype.py +++ /dev/null @@ -1,222 +0,0 @@ -from pypy.interpreter import typedef -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 -from pypy.objspace.std.stdtypedef import StdTypeDef, SMM -from pypy.objspace.std.model import W_Object -from rpython.rlib.rarithmetic import r_uint, string_to_int -from rpython.rlib.objectmodel import instantiate -from rpython.rlib.rbigint import rbigint -from rpython.rlib.rstring import ParseStringError, ParseStringOverflowError -from rpython.rlib import jit - -# ____________________________________________________________ - -def descr_conjugate(space, w_int): - "Returns self, the complex conjugate of any int." - return space.int(w_int) - -def descr_bit_length(space, w_int): - """int.bit_length() -> int - - Number of bits necessary to represent self in binary. - >>> bin(37) - '0b100101' - >>> (37).bit_length() - 6 - """ - val = space.int_w(w_int) - if val < 0: - val = -val - bits = 0 - while val: - bits += 1 - val >>= 1 - return space.wrap(bits) - - -def wrapint(space, x): - 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 - # use r_uint to perform a single comparison (this whole function - # is getting inlined into every caller so keeping the branching - # to a minimum is a good idea) - index = r_uint(x - lower) - if index >= r_uint(upper - lower): - w_res = instantiate(W_IntObject) - else: - w_res = W_IntObject.PREBUILT[index] - # obscure hack to help the CPU cache: we store 'x' even into - # a prebuilt integer's intval. This makes sure that the intval - # field is present in the cache in the common case where it is - # quickly reused. (we could use a prefetch hint if we had that) - w_res.intval = x - return w_res - else: - from pypy.objspace.std.intobject import W_IntObject - return W_IntObject(x) - -# ____________________________________________________________ - - at jit.elidable -def string_to_int_or_long(space, string, base=10): - w_longval = None - value = 0 - try: - value = string_to_int(string, base) - except ParseStringError, e: - raise OperationError(space.w_ValueError, - space.wrap(e.msg)) - except ParseStringOverflowError, e: - w_longval = retry_to_w_long(space, e.parser) - return value, w_longval - -def retry_to_w_long(space, parser): - parser.rewind() - try: - bigint = rbigint._from_numberstring_parser(parser) - except ParseStringError, e: - raise OperationError(space.w_ValueError, - space.wrap(e.msg)) - return space.newlong_from_rbigint(bigint) - - at unwrap_spec(w_x = WrappedDefault(0)) -def descr__new__(space, w_inttype, w_x, w_base=None): - from pypy.objspace.std.intobject import W_IntObject - w_longval = None - w_value = w_x # 'x' is the keyword argument name in CPython - value = 0 - if w_base is None: - ok = False - # check for easy cases - if type(w_value) is W_IntObject: - value = w_value.intval - ok = True - elif space.isinstance_w(w_value, space.w_str): - value, w_longval = string_to_int_or_long(space, space.str_w(w_value)) - ok = True - elif space.isinstance_w(w_value, space.w_unicode): - from pypy.objspace.std.unicodeobject import unicode_to_decimal_w - string = unicode_to_decimal_w(space, w_value) - value, w_longval = string_to_int_or_long(space, string) - ok = True - else: - # If object supports the buffer interface - try: - w_buffer = space.buffer(w_value) - except OperationError, e: - if not e.match(space, space.w_TypeError): - raise - else: - buf = space.interp_w(Buffer, w_buffer) - value, w_longval = string_to_int_or_long(space, buf.as_str()) - ok = True - - if not ok: - # otherwise, use the __int__() or the __trunc__() methods - w_obj = w_value - if space.lookup(w_obj, '__int__') is None: - w_obj = space.trunc(w_obj) - w_obj = space.int(w_obj) - # 'int(x)' should return what x.__int__() returned, which should - # be an int or long or a subclass thereof. - if space.is_w(w_inttype, space.w_int): - return w_obj - # int_w is effectively what we want in this case, - # we cannot construct a subclass of int instance with an - # an overflowing long - try: - value = space.int_w(w_obj) - except OperationError, e: - if e.match(space, space.w_TypeError): - raise OperationError(space.w_ValueError, - space.wrap("value can't be converted to int")) - raise e - else: - base = space.int_w(w_base) - - if space.isinstance_w(w_value, space.w_unicode): - from pypy.objspace.std.unicodeobject import unicode_to_decimal_w - s = unicode_to_decimal_w(space, w_value) - else: - try: - s = space.str_w(w_value) - except OperationError, e: - raise OperationError(space.w_TypeError, - space.wrap("int() can't convert non-string " - "with explicit base")) - - value, w_longval = string_to_int_or_long(space, s, base) - - if w_longval is not None: - if not space.is_w(w_inttype, space.w_int): - raise OperationError(space.w_OverflowError, - space.wrap( - "long int too large to convert to int")) - return w_longval - elif space.is_w(w_inttype, space.w_int): - # common case - return wrapint(space, value) - else: - w_obj = space.allocate_instance(W_IntObject, w_inttype) - W_IntObject.__init__(w_obj, value) - return w_obj - -def descr_get_numerator(space, w_obj): - return space.int(w_obj) - -def descr_get_denominator(space, w_obj): - return space.wrap(1) - -def descr_get_real(space, w_obj): - return space.int(w_obj) - -def descr_get_imag(space, w_obj): - return space.wrap(0) - -# ____________________________________________________________ - -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 - -Convert a string or number to an integer, if possible. A floating point -argument will be truncated towards zero (this does not include a string -representation of a floating point number!) When converting a string, use -the optional base. It is an error to supply a base when converting a -non-string. If the argument is outside the integer range a long object -will be returned instead.''', - __new__ = interp2app(descr__new__), - conjugate = interp2app(descr_conjugate), - bit_length = interp2app(descr_bit_length), - numerator = typedef.GetSetProperty(descr_get_numerator), - 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/model.py b/pypy/objspace/std/model.py --- a/pypy/objspace/std/model.py +++ b/pypy/objspace/std/model.py @@ -32,8 +32,6 @@ # All the Python types that we want to provide in this StdObjSpace class result: from pypy.objspace.std.objecttype import object_typedef - from pypy.objspace.std.booltype import bool_typedef - from pypy.objspace.std.inttype import int_typedef from pypy.objspace.std.floattype import float_typedef from pypy.objspace.std.complextype import complex_typedef from pypy.objspace.std.basestringtype import basestring_typedef @@ -81,6 +79,8 @@ self.pythontypes.append(setobject.W_SetObject.typedef) self.pythontypes.append(setobject.W_FrozensetObject.typedef) self.pythontypes.append(iterobject.W_AbstractSeqIterObject.typedef) + self.pythontypes.append(intobject.W_IntObject.typedef) + self.pythontypes.append(boolobject.W_BoolObject.typedef) # the set of implementation types self.typeorder = { @@ -134,7 +134,7 @@ # XXX build these lists a bit more automatically later self.typeorder[boolobject.W_BoolObject] += [ - (intobject.W_IntObject, boolobject.delegate_Bool2IntObject), +# (intobject.W_IntObject, boolobject.delegate_Bool2IntObject), (floatobject.W_FloatObject, floatobject.delegate_Bool2Float), (longobject.W_LongObject, longobject.delegate_Bool2Long), (complexobject.W_ComplexObject, complexobject.delegate_Bool2Complex), 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 @@ -33,7 +33,7 @@ from pypy.objspace.std.typeobject import W_TypeObject # types -from pypy.objspace.std.inttype import wrapint +from pypy.objspace.std.intobject import wrapint from pypy.objspace.std.stringtype import wrapstr from pypy.objspace.std.unicodetype import wrapunicode 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 @@ -19,14 +19,6 @@ return n n += 1 - def _unwrap_nonimpl(self, func, *args, **kwds): - """ make sure that the expected exception occours, and unwrap it """ - try: - res = func(*args, **kwds) - raise Exception, "should have failed but returned '%s'!" %repr(res) - except FailedToImplement, arg: - return arg.get_w_type(self.space) - def test_int_w(self): assert self.space.int_w(self.space.wrap(42)) == 42 @@ -44,19 +36,19 @@ def test_repr(self): x = 1 f1 = iobj.W_IntObject(x) - result = iobj.repr__Int(self.space, f1) + result = f1.descr_repr(self.space) assert self.space.unwrap(result) == repr(x) def test_str(self): x = 12345 f1 = iobj.W_IntObject(x) - result = iobj.str__Int(self.space, f1) + result = f1.descr_str(self.space) assert self.space.unwrap(result) == str(x) def test_hash(self): x = 42 f1 = iobj.W_IntObject(x) - result = iobj.hash__Int(self.space, f1) + result = f1.descr_hash(self.space) assert result.intval == hash(x) def test_compare(self): @@ -68,89 +60,103 @@ wx = iobj.W_IntObject(x) wy = iobj.W_IntObject(y) res = getattr(operator, op)(x, y) - method = getattr(iobj, '%s__Int_Int' % op) - myres = method(self.space, wx, wy) + method = getattr(wx, 'descr_%s' % op) + myres = method(self.space, wy) assert self.space.unwrap(myres) == res def test_add(self): + space = self.space x = 1 y = 2 f1 = iobj.W_IntObject(x) f2 = iobj.W_IntObject(y) - result = iobj.add__Int_Int(self.space, f1, f2) + result = f1.descr_add(space, f2) assert result.intval == x+y x = sys.maxint y = 1 f1 = iobj.W_IntObject(x) f2 = iobj.W_IntObject(y) - assert self.space.w_OverflowError == ( - self._unwrap_nonimpl(iobj.add__Int_Int, self.space, f1, f2)) + v = f1.descr_add(space, f2) + assert space.isinstance_w(v, space.w_long) + assert space.bigint_w(v).eq(rbigint.fromlong(x + y)) def test_sub(self): + space = self.space x = 1 y = 2 f1 = iobj.W_IntObject(x) f2 = iobj.W_IntObject(y) - result = iobj.sub__Int_Int(self.space, f1, f2) + result = f1.descr_sub(space, f2) assert result.intval == x-y x = sys.maxint y = -1 f1 = iobj.W_IntObject(x) f2 = iobj.W_IntObject(y) - assert self.space.w_OverflowError == ( - self._unwrap_nonimpl(iobj.sub__Int_Int, self.space, f1, f2)) + v = f1.descr_sub(space, f2) + assert space.isinstance_w(v, space.w_long) + assert space.bigint_w(v).eq(rbigint.fromlong(sys.maxint - -1)) def test_mul(self): + space = self.space x = 2 y = 3 f1 = iobj.W_IntObject(x) f2 = iobj.W_IntObject(y) - result = iobj.mul__Int_Int(self.space, f1, f2) + result = f1.descr_mul(space, f2) assert result.intval == x*y x = -sys.maxint-1 y = -1 f1 = iobj.W_IntObject(x) f2 = iobj.W_IntObject(y) - assert self.space.w_OverflowError == ( - self._unwrap_nonimpl(iobj.mul__Int_Int, self.space, f1, f2)) + v = f1.descr_mul(space, f2) + assert space.isinstance_w(v, space.w_long) + assert space.bigint_w(v).eq(rbigint.fromlong(x * y)) def test_div(self): + space = self.space for i in range(10): res = i//3 f1 = iobj.W_IntObject(i) f2 = iobj.W_IntObject(3) - result = iobj.div__Int_Int(self.space, f1, f2) + result = f1.descr_div(space, f2) assert result.intval == res x = -sys.maxint-1 y = -1 f1 = iobj.W_IntObject(x) f2 = iobj.W_IntObject(y) - assert self.space.w_OverflowError == ( - self._unwrap_nonimpl(iobj.div__Int_Int, self.space, f1, f2)) + v = f1.descr_div(space, f2) + assert space.isinstance_w(v, space.w_long) + assert space.bigint_w(v).eq(rbigint.fromlong(x / y)) def test_mod(self): x = 1 y = 2 f1 = iobj.W_IntObject(x) f2 = iobj.W_IntObject(y) - v = iobj.mod__Int_Int(self.space, f1, f2) + v = f1.descr_mod(self.space, f2) assert v.intval == x % y # not that mod cannot overflow def test_divmod(self): + space = self.space x = 1 y = 2 f1 = iobj.W_IntObject(x) f2 = iobj.W_IntObject(y) - ret = iobj.divmod__Int_Int(self.space, f1, f2) - v, w = self.space.unwrap(ret) + ret = f1.descr_divmod(space, f2) + v, w = space.unwrap(ret) assert (v, w) == divmod(x, y) x = -sys.maxint-1 y = -1 f1 = iobj.W_IntObject(x) f2 = iobj.W_IntObject(y) - assert self.space.w_OverflowError == ( - self._unwrap_nonimpl(iobj.divmod__Int_Int, self.space, f1, f2)) + v = f1.descr_divmod(space, f2) + w_q, w_r = space.fixedview(v, 2) + assert space.isinstance_w(w_q, space.w_long) + expected = divmod(x, y) + assert space.bigint_w(w_q).eq(rbigint.fromlong(expected[0])) + # no overflow possible + assert space.unwrap(w_r) == expected[1] def test_pow_iii(self): x = 10 @@ -159,87 +165,93 @@ f1 = iobj.W_IntObject(x) f2 = iobj.W_IntObject(y) f3 = iobj.W_IntObject(z) - v = iobj.pow__Int_Int_Int(self.space, f1, f2, f3) + v = f1.descr_pow(self.space, f2, f3) assert v.intval == pow(x, y, z) f1, f2, f3 = [iobj.W_IntObject(i) for i in (10, -1, 42)] self.space.raises_w(self.space.w_TypeError, - iobj.pow__Int_Int_Int, - self.space, f1, f2, f3) + f1.descr_pow, self.space, f2, f3) f1, f2, f3 = [iobj.W_IntObject(i) for i in (10, 5, 0)] self.space.raises_w(self.space.w_ValueError, - iobj.pow__Int_Int_Int, - self.space, f1, f2, f3) + f1.descr_pow, self.space, f2, f3) def test_pow_iin(self): + space = self.space x = 10 y = 2 f1 = iobj.W_IntObject(x) f2 = iobj.W_IntObject(y) - v = iobj.pow__Int_Int_None(self.space, f1, f2, self.space.w_None) + v = f1.descr_pow(space, f2, space.w_None) assert v.intval == x ** y f1, f2 = [iobj.W_IntObject(i) for i in (10, 20)] - assert self.space.w_OverflowError == ( - self._unwrap_nonimpl(iobj.pow__Int_Int_None, self.space, f1, f2, self.space.w_None)) + v = f1.descr_pow(space, f2, space.w_None) + assert space.isinstance_w(v, space.w_long) + assert space.bigint_w(v).eq(rbigint.fromlong(pow(10, 20))) def test_neg(self): + space = self.space x = 42 f1 = iobj.W_IntObject(x) - v = iobj.neg__Int(self.space, f1) + v = f1.descr_neg(space) assert v.intval == -x x = -sys.maxint-1 f1 = iobj.W_IntObject(x) - assert self.space.w_OverflowError == ( - self._unwrap_nonimpl(iobj.neg__Int, self.space, f1)) + v = f1.descr_neg(space) + assert space.isinstance_w(v, space.w_long) + assert space.bigint_w(v).eq(rbigint.fromlong(-x)) def test_pos(self): x = 42 f1 = iobj.W_IntObject(x) - v = iobj.pos__Int(self.space, f1) + v = f1.descr_pos(self.space) assert v.intval == +x x = -42 f1 = iobj.W_IntObject(x) - v = iobj.pos__Int(self.space, f1) + v = f1.descr_pos(self.space) assert v.intval == +x def test_abs(self): + space = self.space x = 42 f1 = iobj.W_IntObject(x) - v = iobj.abs__Int(self.space, f1) + v = f1.descr_abs(space) assert v.intval == abs(x) x = -42 f1 = iobj.W_IntObject(x) - v = iobj.abs__Int(self.space, f1) + v = f1.descr_abs(space) assert v.intval == abs(x) x = -sys.maxint-1 f1 = iobj.W_IntObject(x) - assert self.space.w_OverflowError == ( - self._unwrap_nonimpl(iobj.abs__Int, self.space, f1)) + v = f1.descr_abs(space) + assert space.isinstance_w(v, space.w_long) + assert space.bigint_w(v).eq(rbigint.fromlong(abs(x))) def test_invert(self): x = 42 f1 = iobj.W_IntObject(x) - v = iobj.invert__Int(self.space, f1) + v = f1.descr_invert(self.space) assert v.intval == ~x def test_lshift(self): + space = self.space x = 12345678 y = 2 f1 = iobj.W_IntObject(x) f2 = iobj.W_IntObject(y) - v = iobj.lshift__Int_Int(self.space, f1, f2) + v = f1.descr_lshift(space, f2) assert v.intval == x << y y = self._longshiftresult(x) f1 = iobj.W_IntObject(x) f2 = iobj.W_IntObject(y) - assert self.space.w_OverflowError == ( - self._unwrap_nonimpl(iobj.lshift__Int_Int, self.space, f1, f2)) + v = f1.descr_lshift(space, f2) + assert space.isinstance_w(v, space.w_long) + assert space.bigint_w(v).eq(rbigint.fromlong(x << y)) def test_rshift(self): x = 12345678 y = 2 f1 = iobj.W_IntObject(x) f2 = iobj.W_IntObject(y) - v = iobj.rshift__Int_Int(self.space, f1, f2) + v = f1.descr_rshift(self.space, f2) assert v.intval == x >> y def test_and(self): @@ -247,7 +259,7 @@ y = 2 f1 = iobj.W_IntObject(x) f2 = iobj.W_IntObject(y) - v = iobj.and__Int_Int(self.space, f1, f2) + v = f1.descr_and(self.space, f2) assert v.intval == x & y def test_xor(self): @@ -255,7 +267,7 @@ y = 2 f1 = iobj.W_IntObject(x) f2 = iobj.W_IntObject(y) - v = iobj.xor__Int_Int(self.space, f1, f2) + v = f1.descr_xor(self.space, f2) assert v.intval == x ^ y def test_or(self): @@ -263,7 +275,7 @@ y = 2 f1 = iobj.W_IntObject(x) f2 = iobj.W_IntObject(y) - v = iobj.or__Int_Int(self.space, f1, f2) + v = f1.descr_or(self.space, f2) assert v.intval == x | y def test_int(self): @@ -274,13 +286,13 @@ def test_oct(self): x = 012345 f1 = iobj.W_IntObject(x) - result = iobj.oct__Int(self.space, f1) + result = f1.descr_oct(self.space) assert self.space.unwrap(result) == oct(x) def test_hex(self): x = 0x12345 f1 = iobj.W_IntObject(x) - result = iobj.hex__Int(self.space, f1) + result = f1.descr_hex(self.space) assert self.space.unwrap(result) == hex(x) class AppTestInt: @@ -498,6 +510,10 @@ b = A(5).real assert type(b) is int + def test_coerce(self): + assert 3 .__coerce__(4) == (3, 4) + assert 3 .__coerce__(4L) == NotImplemented + class AppTestIntOptimizedAdd(AppTestInt): spaceconfig = {"objspace.std.optimized_int_add": True} 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 @@ -341,3 +341,8 @@ assert int(long(3)) == long(3) assert int(A(13)) == 42 + + def test_coerce(self): + assert 3L.__coerce__(4L) == (3L, 4L) + assert 3L.__coerce__(4) == (3, 4) + assert 3L.__coerce__(object()) == NotImplemented From noreply at buildbot.pypy.org Thu Sep 19 14:34:47 2013 From: noreply at buildbot.pypy.org (fijal) Date: Thu, 19 Sep 2013 14:34:47 +0200 (CEST) Subject: [pypy-commit] pypy file-support-in-rpython: tmpfile support Message-ID: <20130919123447.0F27B1C115D@cobra.cs.uni-duesseldorf.de> Author: Maciej Fijalkowski Branch: file-support-in-rpython Changeset: r67006:d4ec042d59fa Date: 2013-09-18 14:35 +0200 http://bitbucket.org/pypy/pypy/changeset/d4ec042d59fa/ Log: tmpfile support diff --git a/rpython/rlib/rfile.py b/rpython/rlib/rfile.py --- a/rpython/rlib/rfile.py +++ b/rpython/rlib/rfile.py @@ -44,7 +44,12 @@ def specialize_call(self, hop): return hop.r_result.rtype_constructor(hop) - #def ll_os_tmpfile(): - #pass +class OSTempfileEntry(ExtRegistryEntry): + _about_ = os.tmpfile - #register_external(os.tmpfile, [], SomeFile(), llimpl=ll_os_tmpfile) + def compute_result_annotation(self): + return SomeFile() + + def specialize_call(self, hop): + return hop.r_result.rtype_tempfile(hop) + diff --git a/rpython/rlib/test/test_rfile.py b/rpython/rlib/test/test_rfile.py --- a/rpython/rlib/test/test_rfile.py +++ b/rpython/rlib/test/test_rfile.py @@ -1,4 +1,5 @@ +import os from rpython.rtyper.test.tool import BaseRtypingTest from rpython.tool.udir import udir from rpython.rlib import rfile @@ -66,3 +67,14 @@ f() self.interpret(f, []) + + def test_tempfile(self): + def f(): + f = os.tmpfile() + f.write("xxx") + f.seek(0) + assert f.read() == "xxx" + f.close() + + f() + self.interpret(f, []) diff --git a/rpython/rtyper/lltypesystem/rfile.py b/rpython/rtyper/lltypesystem/rfile.py --- a/rpython/rtyper/lltypesystem/rfile.py +++ b/rpython/rtyper/lltypesystem/rfile.py @@ -16,19 +16,21 @@ eci = ExternalCompilationInfo(includes=['stdio.h']) -c_open = rffi.llexternal('fopen', [rffi.CCHARP, rffi.CCHARP], - lltype.Ptr(FILE), compilation_info=eci) -c_close = rffi.llexternal('fclose', [lltype.Ptr(FILE)], rffi.INT, - compilation_info=eci) -c_write = rffi.llexternal('fwrite', [rffi.CCHARP, rffi.SIZE_T, rffi.SIZE_T, +def llexternal(*args): + return rffi.llexternal(*args, compilation_info=eci) + +c_open = llexternal('fopen', [rffi.CCHARP, rffi.CCHARP], lltype.Ptr(FILE)) +c_close = llexternal('fclose', [lltype.Ptr(FILE)], rffi.INT) +c_write = llexternal('fwrite', [rffi.CCHARP, rffi.SIZE_T, rffi.SIZE_T, lltype.Ptr(FILE)], rffi.SIZE_T) -c_read = rffi.llexternal('fread', [rffi.CCHARP, rffi.SIZE_T, rffi.SIZE_T, +c_read = llexternal('fread', [rffi.CCHARP, rffi.SIZE_T, rffi.SIZE_T, lltype.Ptr(FILE)], rffi.SIZE_T) -c_feof = rffi.llexternal('feof', [lltype.Ptr(FILE)], rffi.INT) -c_ferror = rffi.llexternal('ferror', [lltype.Ptr(FILE)], rffi.INT) -c_clearerror = rffi.llexternal('clearerr', [lltype.Ptr(FILE)], lltype.Void) -c_fseek = rffi.llexternal('fseek', [lltype.Ptr(FILE), rffi.LONG, rffi.INT], +c_feof = llexternal('feof', [lltype.Ptr(FILE)], rffi.INT) +c_ferror = llexternal('ferror', [lltype.Ptr(FILE)], rffi.INT) +c_clearerror = llexternal('clearerr', [lltype.Ptr(FILE)], lltype.Void) +c_fseek = llexternal('fseek', [lltype.Ptr(FILE), rffi.LONG, rffi.INT], rffi.INT) +c_tmpfile = llexternal('tmpfile', [], lltype.Ptr(FILE)) def ll_open(name, mode): file_wrapper = lltype.malloc(FILE_WRAPPER) @@ -45,6 +47,15 @@ lltype.free(ll_mode, flavor='raw') return file_wrapper +def ll_tmpfile(): + file_wrapper = lltype.malloc(FILE_WRAPPER) + res = c_tmpfile() + if not res: + errno = rposix.get_errno() + raise OSError(errno, os.strerror(errno)) + file_wrapper.file = res + return file_wrapper + def ll_write(file_wrapper, value): ll_file = file_wrapper.file if not ll_file: @@ -113,7 +124,7 @@ res = c_fseek(ll_file, pos, whence) if res == -1: errno = rposix.get_errno() - raise OSError(errno, os.strerror(errno)) + raise OSError(errno, os.strerror(errno)) def ll_close(file_wrapper): if file_wrapper.file: @@ -145,6 +156,14 @@ return hop.genop('direct_call', [v_open, arg_0, arg_1], resulttype=self) + def rtype_tempfile(self, hop): + tmpfile = hop.rtyper.getannmixlevel().delayedfunction( + ll_tmpfile, [], annmodel.SomePtr(self.lowleveltype)) + v_tmpfile = hop.inputconst(lltype.typeOf(tmpfile), tmpfile) + hop.exception_is_here() + return hop.genop('direct_call', [v_tmpfile], resulttype=self) + + def rtype_method_write(self, hop): args_v = hop.inputargs(self, string_repr) hop.exception_is_here() @@ -173,3 +192,4 @@ arg_2 = hop.inputarg(lltype.Signed, 2) hop.exception_is_here() return hop.gendirectcall(ll_seek, r_self, arg_1, arg_2) + From noreply at buildbot.pypy.org Thu Sep 19 20:27:23 2013 From: noreply at buildbot.pypy.org (mattip) Date: Thu, 19 Sep 2013 20:27:23 +0200 (CEST) Subject: [pypy-commit] pypy pypy-pyarray: merge default into branch Message-ID: <20130919182723.AAB2D1C115D@cobra.cs.uni-duesseldorf.de> Author: Matti Picus Branch: pypy-pyarray Changeset: r67007:bf25a3ff4bbe Date: 2013-09-18 18:15 +0300 http://bitbucket.org/pypy/pypy/changeset/bf25a3ff4bbe/ Log: merge default into branch diff too long, truncating to 2000 out of 19597 lines diff --git a/dotviewer/drawgraph.py b/dotviewer/drawgraph.py --- a/dotviewer/drawgraph.py +++ b/dotviewer/drawgraph.py @@ -22,6 +22,7 @@ 'yellow': (255,255,0), } re_nonword=re.compile(r'([^0-9a-zA-Z_.]+)') +re_linewidth=re.compile(r'setlinewidth\((\d+(\.\d*)?|\.\d+)\)') def combine(color1, color2, alpha): r1, g1, b1 = color1 @@ -138,6 +139,13 @@ self.yl = float(yl) rest = rest[3:] self.style, self.color = rest + linematch = re_linewidth.match(self.style) + if linematch: + num = linematch.group(1) + self.linewidth = int(round(float(num))) + self.style = self.style[linematch.end(0):] + else: + self.linewidth = 1 self.highlight = False self.cachedbezierpoints = None self.cachedarrowhead = None @@ -520,8 +528,8 @@ fgcolor = highlight_color(fgcolor) points = [self.map(*xy) for xy in edge.bezierpoints()] - def drawedgebody(points=points, fgcolor=fgcolor): - pygame.draw.lines(self.screen, fgcolor, False, points) + def drawedgebody(points=points, fgcolor=fgcolor, width=edge.linewidth): + pygame.draw.lines(self.screen, fgcolor, False, points, width) edgebodycmd.append(drawedgebody) points = [self.map(*xy) for xy in edge.arrowhead()] diff --git a/dotviewer/graphparse.py b/dotviewer/graphparse.py --- a/dotviewer/graphparse.py +++ b/dotviewer/graphparse.py @@ -152,7 +152,8 @@ try: plaincontent = dot2plain_graphviz(content, contenttype) except PlainParseError, e: - print e - # failed, retry via codespeak - plaincontent = dot2plain_codespeak(content, contenttype) + raise + ##print e + ### failed, retry via codespeak + ##plaincontent = dot2plain_codespeak(content, contenttype) return list(parse_plain(graph_id, plaincontent, links, fixedfont)) diff --git a/dotviewer/test/test_interactive.py b/dotviewer/test/test_interactive.py --- a/dotviewer/test/test_interactive.py +++ b/dotviewer/test/test_interactive.py @@ -34,6 +34,23 @@ } ''' +SOURCE2=r'''digraph f { + a; d; e; f; g; h; i; j; k; l; + a -> d [penwidth=1, style="setlinewidth(1)"]; + d -> e [penwidth=2, style="setlinewidth(2)"]; + e -> f [penwidth=4, style="setlinewidth(4)"]; + f -> g [penwidth=8, style="setlinewidth(8)"]; + g -> h [penwidth=16, style="setlinewidth(16)"]; + h -> i [penwidth=32, style="setlinewidth(32)"]; + i -> j [penwidth=64, style="setlinewidth(64)"]; + j -> k [penwidth=128, style="setlinewidth(128)"]; + k -> l [penwidth=256, style="setlinewidth(256)"]; +}''' + + + + + def setup_module(mod): if not option.pygame: py.test.skip("--pygame not enabled") @@ -161,3 +178,10 @@ page = MyPage(str(dotfile)) page.fixedfont = True graphclient.display_page(page) + +def test_linewidth(): + udir.join("graph2.dot").write(SOURCE2) + from dotviewer import graphpage, graphclient + dotfile = udir.join('graph2.dot') + page = graphpage.DotFileGraphPage(str(dotfile)) + graphclient.display_page(page) diff --git a/lib-python/2.7/argparse.py b/lib-python/2.7/argparse.py --- a/lib-python/2.7/argparse.py +++ b/lib-python/2.7/argparse.py @@ -1780,7 +1780,19 @@ # error if this argument is not allowed with other previously # seen arguments, assuming that actions that use the default # value don't really count as "present" - if argument_values is not action.default: + + # XXX PyPy bug-to-bug compatibility: "is" on primitive types + # is not consistent in CPython. We'll assume it is close + # enough for ints (which is true only for "small ints"), but + # for floats and longs and complexes we'll go for the option + # of forcing "is" to say False, like it usually does on + # CPython. A fix is pending on CPython trunk + # (http://bugs.python.org/issue18943) but that might change + # the details of the semantics and so not be applied to 2.7. + # See the line AA below. + + if (argument_values is not action.default or + type(argument_values) in (float, long, complex)): # AA seen_non_default_actions.add(action) for conflict_action in action_conflicts.get(action, []): if conflict_action in seen_non_default_actions: diff --git a/lib-python/2.7/socket.py b/lib-python/2.7/socket.py --- a/lib-python/2.7/socket.py +++ b/lib-python/2.7/socket.py @@ -165,6 +165,8 @@ # All _delegate_methods must also be initialized here. send = recv = recv_into = sendto = recvfrom = recvfrom_into = _dummy __getattr__ = _dummy + def _drop(self): + pass # Wrapper around platform socket objects. This implements # a platform-independent dup() functionality. The @@ -179,12 +181,21 @@ def __init__(self, family=AF_INET, type=SOCK_STREAM, proto=0, _sock=None): if _sock is None: _sock = _realsocket(family, type, proto) - elif _type(_sock) is _realsocket: + else: + # PyPy note about refcounting: implemented with _reuse()/_drop() + # on the class '_socket.socket'. Python 3 did it differently + # with a reference counter on this class 'socket._socketobject' + # instead, but it is a less compatible change. + + # Note that a few libraries (like eventlet) poke at the + # private implementation of socket.py, passing custom + # objects to _socketobject(). These libraries need the + # following fix for use on PyPy: the custom objects need + # methods _reuse() and _drop() that maintains an explicit + # reference counter, starting at 0. When it drops back to + # zero, close() must be called. _sock._reuse() - # PyPy note about refcounting: implemented with _reuse()/_drop() - # on the class '_socket.socket'. Python 3 did it differently - # with a reference counter on this class 'socket._socketobject' - # instead, but it is a less compatible change (breaks eventlet). + self._sock = _sock def send(self, data, flags=0): @@ -216,9 +227,8 @@ def close(self): s = self._sock - if type(s) is _realsocket: - s._drop() self._sock = _closedsocket() + s._drop() close.__doc__ = _realsocket.close.__doc__ def accept(self): @@ -280,8 +290,14 @@ "_close"] def __init__(self, sock, mode='rb', bufsize=-1, close=False): - if type(sock) is _realsocket: - sock._reuse() + # Note that a few libraries (like eventlet) poke at the + # private implementation of socket.py, passing custom + # objects to _fileobject(). These libraries need the + # following fix for use on PyPy: the custom objects need + # methods _reuse() and _drop() that maintains an explicit + # reference counter, starting at 0. When it drops back to + # zero, close() must be called. + sock._reuse() self._sock = sock self.mode = mode # Not actually used in this version if bufsize < 0: @@ -317,11 +333,11 @@ self.flush() finally: s = self._sock - if type(s) is _realsocket: + self._sock = None + if s is not None: s._drop() - if self._close: - self._sock.close() - self._sock = None + if self._close: + s.close() def __del__(self): try: diff --git a/lib-python/2.7/ssl.py b/lib-python/2.7/ssl.py --- a/lib-python/2.7/ssl.py +++ b/lib-python/2.7/ssl.py @@ -110,6 +110,12 @@ suppress_ragged_eofs=True, ciphers=None): socket.__init__(self, _sock=sock._sock) + # "close" the original socket: it is not usable any more. + # this only calls _drop(), which should not actually call + # the operating system's close() because the reference + # counter is greater than 1 (we hold one too). + sock.close() + if ciphers is None and ssl_version != _SSLv2_IF_EXISTS: ciphers = _DEFAULT_CIPHERS @@ -352,11 +358,19 @@ works with the SSL connection. Just use the code from the socket module.""" - self._makefile_refs += 1 # close=True so as to decrement the reference count when done with # the file-like object. return _fileobject(self, mode, bufsize, close=True) + def _reuse(self): + self._makefile_refs += 1 + + def _drop(self): + if self._makefile_refs < 1: + self.close() + else: + self._makefile_refs -= 1 + def wrap_socket(sock, keyfile=None, certfile=None, diff --git a/lib-python/2.7/test/test_socket.py b/lib-python/2.7/test/test_socket.py --- a/lib-python/2.7/test/test_socket.py +++ b/lib-python/2.7/test/test_socket.py @@ -1066,6 +1066,9 @@ def recv(self, size): return self._recv_step.next()() + def _reuse(self): pass + def _drop(self): pass + @staticmethod def _raise_eintr(): raise socket.error(errno.EINTR) @@ -1321,7 +1324,8 @@ closed = False def flush(self): pass def close(self): self.closed = True - def _decref_socketios(self): pass + def _reuse(self): pass + def _drop(self): pass # must not close unless we request it: the original use of _fileobject # by module socket requires that the underlying socket not be closed until diff --git a/lib-python/2.7/test/test_urllib2.py b/lib-python/2.7/test/test_urllib2.py --- a/lib-python/2.7/test/test_urllib2.py +++ b/lib-python/2.7/test/test_urllib2.py @@ -270,6 +270,8 @@ self.reason = reason def read(self): return '' + def _reuse(self): pass + def _drop(self): pass class MockHTTPClass: def __init__(self): diff --git a/lib-python/2.7/urllib2.py b/lib-python/2.7/urllib2.py --- a/lib-python/2.7/urllib2.py +++ b/lib-python/2.7/urllib2.py @@ -1193,6 +1193,8 @@ # out of socket._fileobject() and into a base class. r.recv = r.read + r._reuse = lambda: None + r._drop = lambda: None fp = socket._fileobject(r, close=True) resp = addinfourl(fp, r.msg, req.get_full_url()) diff --git a/lib-python/2.7/uuid.py b/lib-python/2.7/uuid.py --- a/lib-python/2.7/uuid.py +++ b/lib-python/2.7/uuid.py @@ -44,6 +44,8 @@ UUID('00010203-0405-0607-0809-0a0b0c0d0e0f') """ +import struct + __author__ = 'Ka-Ping Yee ' RESERVED_NCS, RFC_4122, RESERVED_MICROSOFT, RESERVED_FUTURE = [ @@ -125,25 +127,39 @@ overriding the given 'hex', 'bytes', 'bytes_le', 'fields', or 'int'. """ - if [hex, bytes, bytes_le, fields, int].count(None) != 4: - raise TypeError('need one of hex, bytes, bytes_le, fields, or int') if hex is not None: + if (bytes is not None or bytes_le is not None or + fields is not None or int is not None): + raise TypeError('if the hex argument is given, bytes,' + ' bytes_le, fields, and int need to be None') hex = hex.replace('urn:', '').replace('uuid:', '') hex = hex.strip('{}').replace('-', '') if len(hex) != 32: raise ValueError('badly formed hexadecimal UUID string') int = long(hex, 16) - if bytes_le is not None: + elif bytes_le is not None: + if bytes is not None or fields is not None or int is not None: + raise TypeError('if the bytes_le argument is given, bytes,' + ' fields, and int need to be None') if len(bytes_le) != 16: raise ValueError('bytes_le is not a 16-char string') bytes = (bytes_le[3] + bytes_le[2] + bytes_le[1] + bytes_le[0] + bytes_le[5] + bytes_le[4] + bytes_le[7] + bytes_le[6] + bytes_le[8:]) - if bytes is not None: + int = (struct.unpack('>Q', bytes[:8])[0] << 64 | + struct.unpack('>Q', bytes[8:])[0]) + elif bytes is not None: + if fields is not None or int is not None: + raise TypeError('if the bytes argument is given, fields ' + 'and int need to be None') if len(bytes) != 16: raise ValueError('bytes is not a 16-char string') - int = long(('%02x'*16) % tuple(map(ord, bytes)), 16) - if fields is not None: + int = (struct.unpack('>Q', bytes[:8])[0] << 64 | + struct.unpack('>Q', bytes[8:])[0]) + elif fields is not None: + if int is not None: + raise TypeError('if the fields argument is given, int needs' + ' to be None') if len(fields) != 6: raise ValueError('fields is not a 6-tuple') (time_low, time_mid, time_hi_version, @@ -163,9 +179,12 @@ clock_seq = (clock_seq_hi_variant << 8L) | clock_seq_low int = ((time_low << 96L) | (time_mid << 80L) | (time_hi_version << 64L) | (clock_seq << 48L) | node) - if int is not None: + elif int is not None: if not 0 <= int < 1<<128L: raise ValueError('int is out of range (need a 128-bit value)') + else: + raise TypeError('one of hex, bytes, bytes_le, fields,' + ' or int need to be not None') if version is not None: if not 1 <= version <= 5: raise ValueError('illegal version number') @@ -175,7 +194,7 @@ # Set the version number. int &= ~(0xf000 << 64L) int |= version << 76L - self.__dict__['int'] = int + object.__setattr__(self, 'int', int) def __cmp__(self, other): if isinstance(other, UUID): diff --git a/lib_pypy/_curses.py b/lib_pypy/_curses.py --- a/lib_pypy/_curses.py +++ b/lib_pypy/_curses.py @@ -1,6 +1,9 @@ """Reimplementation of the standard extension module '_curses' using cffi.""" import sys +if sys.platform == 'win32': + #This module does not exist in windows + raise ImportError('No module named _curses') from functools import wraps from cffi import FFI diff --git a/lib_pypy/_sqlite3.py b/lib_pypy/_sqlite3.py --- a/lib_pypy/_sqlite3.py +++ b/lib_pypy/_sqlite3.py @@ -1229,7 +1229,10 @@ if cvt is not None: param = cvt(param) - param = adapt(param) + try: + param = adapt(param) + except: + pass # And use previous value if param is None: rc = _lib.sqlite3_bind_null(self._statement, idx) @@ -1305,7 +1308,7 @@ for i in xrange(_lib.sqlite3_column_count(self._statement)): name = _lib.sqlite3_column_name(self._statement, i) if name: - name = _ffi.string(name).decode('utf-8').split("[")[0].strip() + name = _ffi.string(name).split("[")[0].strip() desc.append((name, None, None, None, None, None, None)) return desc diff --git a/lib_pypy/_tkinter/__init__.py b/lib_pypy/_tkinter/__init__.py --- a/lib_pypy/_tkinter/__init__.py +++ b/lib_pypy/_tkinter/__init__.py @@ -22,6 +22,7 @@ READABLE = tklib.TCL_READABLE WRITABLE = tklib.TCL_WRITABLE EXCEPTION = tklib.TCL_EXCEPTION +DONT_WAIT = tklib.TCL_DONT_WAIT def create(screenName=None, baseName=None, className=None, interactive=False, wantobjects=False, wantTk=True, diff --git a/lib_pypy/_tkinter/app.py b/lib_pypy/_tkinter/app.py --- a/lib_pypy/_tkinter/app.py +++ b/lib_pypy/_tkinter/app.py @@ -4,7 +4,23 @@ from . import TclError from .tclobj import TclObject, FromObj, AsObj, TypeCache +import contextlib import sys +import threading +import time + + +class _DummyLock(object): + "A lock-like object that does not do anything" + def acquire(self): + pass + def release(self): + pass + def __enter__(self): + pass + def __exit__(self, *exc): + pass + def varname_converter(input): if isinstance(input, TclObject): @@ -37,17 +53,18 @@ def PythonCmd(clientData, interp, argc, argv): self = tkffi.from_handle(clientData) assert self.app.interp == interp - try: - args = [tkffi.string(arg) for arg in argv[1:argc]] - result = self.func(*args) - obj = AsObj(result) - tklib.Tcl_SetObjResult(interp, obj) - except: - self.app.errorInCmd = True - self.app.exc_info = sys.exc_info() - return tklib.TCL_ERROR - else: - return tklib.TCL_OK + with self.app._tcl_lock_released(): + try: + args = [tkffi.string(arg) for arg in argv[1:argc]] + result = self.func(*args) + obj = AsObj(result) + tklib.Tcl_SetObjResult(interp, obj) + except: + self.app.errorInCmd = True + self.app.exc_info = sys.exc_info() + return tklib.TCL_ERROR + else: + return tklib.TCL_OK @tkffi.callback("Tcl_CmdDeleteProc") def PythonCmdDelete(clientData): @@ -58,6 +75,8 @@ class TkApp(object): + _busywaitinterval = 0.02 # 20ms. + def __new__(cls, screenName, baseName, className, interactive, wantobjects, wantTk, sync, use): if not wantobjects: @@ -73,6 +92,12 @@ self.quitMainLoop = False self.errorInCmd = False + if not self.threaded: + # TCL is not thread-safe, calls needs to be serialized. + self._tcl_lock = threading.Lock() + else: + self._tcl_lock = _DummyLock() + self._typeCache = TypeCache() self._commands = {} @@ -133,6 +158,13 @@ if self.threaded and self.thread_id != tklib.Tcl_GetCurrentThread(): raise RuntimeError("Calling Tcl from different appartment") + @contextlib.contextmanager + def _tcl_lock_released(self): + "Context manager to temporarily release the tcl lock." + self._tcl_lock.release() + yield + self._tcl_lock.acquire() + def loadtk(self): # We want to guard against calling Tk_Init() multiple times err = tklib.Tcl_Eval(self.interp, "info exists tk_version") @@ -159,22 +191,25 @@ flags=tklib.TCL_LEAVE_ERR_MSG if global_only: flags |= tklib.TCL_GLOBAL_ONLY - res = tklib.Tcl_GetVar2Ex(self.interp, name1, name2, flags) - if not res: - self.raiseTclError() - assert self._wantobjects - return FromObj(self, res) + with self._tcl_lock: + res = tklib.Tcl_GetVar2Ex(self.interp, name1, name2, flags) + if not res: + self.raiseTclError() + assert self._wantobjects + return FromObj(self, res) def _setvar(self, name1, value, global_only=False): name1 = varname_converter(name1) + # XXX Acquire tcl lock??? newval = AsObj(value) flags=tklib.TCL_LEAVE_ERR_MSG if global_only: flags |= tklib.TCL_GLOBAL_ONLY - res = tklib.Tcl_SetVar2Ex(self.interp, name1, tkffi.NULL, - newval, flags) - if not res: - self.raiseTclError() + with self._tcl_lock: + res = tklib.Tcl_SetVar2Ex(self.interp, name1, tkffi.NULL, + newval, flags) + if not res: + self.raiseTclError() def _unsetvar(self, name1, name2=None, global_only=False): name1 = varname_converter(name1) @@ -183,9 +218,10 @@ flags=tklib.TCL_LEAVE_ERR_MSG if global_only: flags |= tklib.TCL_GLOBAL_ONLY - res = tklib.Tcl_UnsetVar2(self.interp, name1, name2, flags) - if res == tklib.TCL_ERROR: - self.raiseTclError() + with self._tcl_lock: + res = tklib.Tcl_UnsetVar2(self.interp, name1, name2, flags) + if res == tklib.TCL_ERROR: + self.raiseTclError() def getvar(self, name1, name2=None): return self._var_invoke(self._getvar, name1, name2) @@ -219,9 +255,10 @@ if self.threaded and self.thread_id != tklib.Tcl_GetCurrentThread(): raise NotImplementedError("Call from another thread") - res = tklib.Tcl_CreateCommand( - self.interp, cmdName, _CommandData.PythonCmd, - clientData, _CommandData.PythonCmdDelete) + with self._tcl_lock: + res = tklib.Tcl_CreateCommand( + self.interp, cmdName, _CommandData.PythonCmd, + clientData, _CommandData.PythonCmdDelete) if not res: raise TclError("can't create Tcl command") @@ -229,7 +266,8 @@ if self.threaded and self.thread_id != tklib.Tcl_GetCurrentThread(): raise NotImplementedError("Call from another thread") - res = tklib.Tcl_DeleteCommand(self.interp, cmdName) + with self._tcl_lock: + res = tklib.Tcl_DeleteCommand(self.interp, cmdName) if res == -1: raise TclError("can't delete Tcl command") @@ -256,11 +294,12 @@ tklib.Tcl_IncrRefCount(obj) objects[i] = obj - res = tklib.Tcl_EvalObjv(self.interp, argc, objects, flags) - if res == tklib.TCL_ERROR: - self.raiseTclError() - else: - result = self._callResult() + with self._tcl_lock: + res = tklib.Tcl_EvalObjv(self.interp, argc, objects, flags) + if res == tklib.TCL_ERROR: + self.raiseTclError() + else: + result = self._callResult() finally: for obj in objects: if obj: @@ -280,17 +319,19 @@ def eval(self, script): self._check_tcl_appartment() - res = tklib.Tcl_Eval(self.interp, script) - if res == tklib.TCL_ERROR: - self.raiseTclError() - return tkffi.string(tklib.Tcl_GetStringResult(self.interp)) + with self._tcl_lock: + res = tklib.Tcl_Eval(self.interp, script) + if res == tklib.TCL_ERROR: + self.raiseTclError() + return tkffi.string(tklib.Tcl_GetStringResult(self.interp)) def evalfile(self, filename): self._check_tcl_appartment() - res = tklib.Tcl_EvalFile(self.interp, filename) - if res == tklib.TCL_ERROR: - self.raiseTclError() - return tkffi.string(tklib.Tcl_GetStringResult(self.interp)) + with self._tcl_lock: + res = tklib.Tcl_EvalFile(self.interp, filename) + if res == tklib.TCL_ERROR: + self.raiseTclError() + return tkffi.string(tklib.Tcl_GetStringResult(self.interp)) def split(self, arg): if isinstance(arg, tuple): @@ -375,7 +416,10 @@ if self.threaded: result = tklib.Tcl_DoOneEvent(0) else: - raise NotImplementedError("TCL configured without threads") + with self._tcl_lock: + result = tklib.Tcl_DoOneEvent(tklib.TCL_DONT_WAIT) + if result == 0: + time.sleep(self._busywaitinterval) if result < 0: break diff --git a/lib_pypy/_tkinter/tklib.py b/lib_pypy/_tkinter/tklib.py --- a/lib_pypy/_tkinter/tklib.py +++ b/lib_pypy/_tkinter/tklib.py @@ -1,6 +1,7 @@ # C bindings with libtcl and libtk. from cffi import FFI +import sys tkffi = FFI() @@ -18,6 +19,8 @@ #define TCL_EVAL_DIRECT ... #define TCL_EVAL_GLOBAL ... +#define TCL_DONT_WAIT ... + typedef unsigned short Tcl_UniChar; typedef ... Tcl_Interp; typedef ...* Tcl_ThreadId; @@ -102,6 +105,17 @@ int Tk_GetNumMainWindows(); """) +# XXX find a better way to detect paths +# XXX pick up CPPFLAGS and LDFLAGS and add to these paths? +if sys.platform.startswith("openbsd"): + incdirs = ['/usr/local/include/tcl8.5', '/usr/local/include/tk8.5', '/usr/X11R6/include'] + linklibs = ['tk85', 'tcl85'] + libdirs = ['/usr/local/lib', '/usr/X11R6/lib'] +else: + incdirs=['/usr/include/tcl'] + linklibs=['tcl', 'tk'] + libdirs = [] + tklib = tkffi.verify(""" #include #include @@ -109,6 +123,7 @@ char *get_tk_version() { return TK_VERSION; } char *get_tcl_version() { return TCL_VERSION; } """, -include_dirs=['/usr/include/tcl'], -libraries=['tcl', 'tk'], +include_dirs=incdirs, +libraries=linklibs, +library_dirs = libdirs ) diff --git a/lib_pypy/cffi.egg-info b/lib_pypy/cffi.egg-info --- a/lib_pypy/cffi.egg-info +++ b/lib_pypy/cffi.egg-info @@ -1,6 +1,6 @@ Metadata-Version: 1.0 Name: cffi -Version: 0.6 +Version: 0.7 Summary: Foreign Function Interface for Python calling C code. Home-page: http://cffi.readthedocs.org Author: Armin Rigo, Maciej Fijalkowski diff --git a/lib_pypy/cffi/__init__.py b/lib_pypy/cffi/__init__.py --- a/lib_pypy/cffi/__init__.py +++ b/lib_pypy/cffi/__init__.py @@ -4,5 +4,5 @@ from .api import FFI, CDefError, FFIError from .ffiplatform import VerificationError, VerificationMissing -__version__ = "0.7" -__version_info__ = (0, 7) +__version__ = "0.7.2" +__version_info__ = (0, 7, 2) diff --git a/lib_pypy/cffi/api.py b/lib_pypy/cffi/api.py --- a/lib_pypy/cffi/api.py +++ b/lib_pypy/cffi/api.py @@ -54,7 +54,8 @@ # _cffi_backend.so compiled. import _cffi_backend as backend from . import __version__ - assert backend.__version__ == __version__ + assert (backend.__version__ == __version__ or + backend.__version__ == __version__[:3]) # (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.) diff --git a/lib_pypy/cffi/commontypes.py b/lib_pypy/cffi/commontypes.py --- a/lib_pypy/cffi/commontypes.py +++ b/lib_pypy/cffi/commontypes.py @@ -30,7 +30,9 @@ elif result in model.PrimitiveType.ALL_PRIMITIVE_TYPES: result = model.PrimitiveType(result) else: - assert commontype != result + if commontype == result: + raise api.FFIError("Unsupported type: %r. Please file a bug " + "if you think it should be." % (commontype,)) result = resolve_common_type(result) # recursively assert isinstance(result, model.BaseTypeByIdentity) _CACHE[commontype] = result diff --git a/lib_pypy/cffi/cparser.py b/lib_pypy/cffi/cparser.py --- a/lib_pypy/cffi/cparser.py +++ b/lib_pypy/cffi/cparser.py @@ -290,13 +290,26 @@ # assume a primitive type. get it from .names, but reduce # synonyms to a single chosen combination names = list(type.names) - if names == ['signed'] or names == ['unsigned']: - names.append('int') - if names[0] == 'signed' and names != ['signed', 'char']: - names.pop(0) - if (len(names) > 1 and names[-1] == 'int' - and names != ['unsigned', 'int']): - names.pop() + if names != ['signed', 'char']: # keep this unmodified + prefixes = {} + while names: + name = names[0] + if name in ('short', 'long', 'signed', 'unsigned'): + prefixes[name] = prefixes.get(name, 0) + 1 + del names[0] + else: + break + # ignore the 'signed' prefix below, and reorder the others + newnames = [] + for prefix in ('unsigned', 'short', 'long'): + for i in range(prefixes.get(prefix, 0)): + newnames.append(prefix) + if not names: + names = ['int'] # implicitly + if names == ['int']: # but kill it if 'short' or 'long' + if 'short' in prefixes or 'long' in prefixes: + names = [] + names = newnames + names ident = ' '.join(names) if ident == 'void': return model.void_type @@ -500,8 +513,8 @@ self._partial_length = True return None # - raise api.FFIError("unsupported non-constant or " - "not immediately constant expression") + raise api.FFIError("unsupported expression: expected a " + "simple numeric constant") def _build_enum_type(self, explicit_name, decls): if decls is not None: diff --git a/lib_pypy/cffi/vengine_gen.py b/lib_pypy/cffi/vengine_gen.py --- a/lib_pypy/cffi/vengine_gen.py +++ b/lib_pypy/cffi/vengine_gen.py @@ -61,7 +61,9 @@ def load_library(self): # import it with the CFFI backend backend = self.ffi._backend - module = backend.load_library(self.verifier.modulefilename) + # needs to make a path that contains '/', on Posix + filename = os.path.join(os.curdir, self.verifier.modulefilename) + module = backend.load_library(filename) # # call loading_gen_struct() to get the struct layout inferred by # the C compiler diff --git a/lib_pypy/datetime.py b/lib_pypy/datetime.py --- a/lib_pypy/datetime.py +++ b/lib_pypy/datetime.py @@ -40,9 +40,9 @@ # for all computations. See the book for algorithms for converting between # proleptic Gregorian ordinals and many other calendar systems. -_DAYS_IN_MONTH = [None, 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31] +_DAYS_IN_MONTH = [-1, 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31] -_DAYS_BEFORE_MONTH = [None] +_DAYS_BEFORE_MONTH = [-1] dbm = 0 for dim in _DAYS_IN_MONTH[1:]: _DAYS_BEFORE_MONTH.append(dbm) diff --git a/lib_pypy/readline.egg-info b/lib_pypy/readline.egg-info new file mode 100644 --- /dev/null +++ b/lib_pypy/readline.egg-info @@ -0,0 +1,10 @@ +Metadata-Version: 1.0 +Name: readline +Version: 6.2.4.1 +Summary: Hack to make "pip install readline" happy and do nothing +Home-page: UNKNOWN +Author: UNKNOWN +Author-email: UNKNOWN +License: UNKNOWN +Description: UNKNOWN +Platform: UNKNOWN diff --git a/pypy/config/pypyoption.py b/pypy/config/pypyoption.py --- a/pypy/config/pypyoption.py +++ b/pypy/config/pypyoption.py @@ -127,11 +127,6 @@ pypy_optiondescription = OptionDescription("objspace", "Object Space Options", [ - OptionDescription("opcodes", "opcodes to enable in the interpreter", [ - BoolOption("CALL_METHOD", "emit a special bytecode for expr.name()", - default=False), - ]), - OptionDescription("usemodules", "Which Modules should be used", [ BoolOption(modname, "use module %s" % (modname, ), default=modname in default_modules, @@ -259,9 +254,6 @@ BoolOption("optimized_int_add", "special case the addition of two integers in BINARY_ADD", default=False), - BoolOption("optimized_comparison_op", - "special case the comparison of integers", - default=False), BoolOption("optimized_list_getitem", "special case the 'list[integer]' expressions", default=False), @@ -307,7 +299,6 @@ # all the good optimizations for PyPy should be listed here if level in ['2', '3', 'jit']: - config.objspace.opcodes.suggest(CALL_METHOD=True) config.objspace.std.suggest(withrangelist=True) config.objspace.std.suggest(withmethodcache=True) config.objspace.std.suggest(withprebuiltchar=True) diff --git a/pypy/doc/_ref.txt b/pypy/doc/_ref.txt --- a/pypy/doc/_ref.txt +++ b/pypy/doc/_ref.txt @@ -98,8 +98,6 @@ .. _`rpython/rtyper/memory/gc/hybrid.py`: https://bitbucket.org/pypy/pypy/src/default/rpython/rtyper/memory/gc/hybrid.py .. _`rpython/rtyper/memory/gc/minimarkpage.py`: https://bitbucket.org/pypy/pypy/src/default/rpython/rtyper/memory/gc/minimarkpage.py .. _`rpython/rtyper/memory/gc/semispace.py`: https://bitbucket.org/pypy/pypy/src/default/rpython/rtyper/memory/gc/semispace.py -.. _`rpython/rtyper/ootypesystem/`: https://bitbucket.org/pypy/pypy/src/default/rpython/rtyper/ootypesystem/ -.. _`rpython/rtyper/ootypesystem/ootype.py`: https://bitbucket.org/pypy/pypy/src/default/rpython/rtyper/ootypesystem/ootype.py .. _`rpython/rtyper/rint.py`: https://bitbucket.org/pypy/pypy/src/default/rpython/rtyper/rint.py .. _`rpython/rtyper/rlist.py`: https://bitbucket.org/pypy/pypy/src/default/rpython/rtyper/rlist.py .. _`rpython/rtyper/rmodel.py`: https://bitbucket.org/pypy/pypy/src/default/rpython/rtyper/rmodel.py diff --git a/pypy/doc/coding-guide.rst b/pypy/doc/coding-guide.rst --- a/pypy/doc/coding-guide.rst +++ b/pypy/doc/coding-guide.rst @@ -339,9 +339,10 @@ + methods and other class attributes do not change after startup + single inheritance is fully supported -+ simple mixins somewhat work too, but the mixed in class needs a - ``_mixin_ = True`` class attribute. isinstance checks against the - mixin type will fail when translated. ++ use `rpython.rlib.objectmodel.import_from_mixin(M)` in a class + body to copy the whole content of a class `M`. This can be used + to implement mixins: functions and staticmethods are duplicated + (the other class attributes are just copied unmodified). + classes are first-class objects too diff --git a/pypy/doc/config/objspace.opcodes.CALL_METHOD.txt b/pypy/doc/config/objspace.opcodes.CALL_METHOD.txt deleted file mode 100644 --- a/pypy/doc/config/objspace.opcodes.CALL_METHOD.txt +++ /dev/null @@ -1,10 +0,0 @@ -Enable a pair of bytecodes that speed up method calls. -See ``pypy.interpreter.callmethod`` for a description. - -The goal is to avoid creating the bound method object in the common -case. So far, this only works for calls with no keyword, no ``*arg`` -and no ``**arg`` but it would be easy to extend. - -For more information, see the section in `Standard Interpreter Optimizations`_. - -.. _`Standard Interpreter Optimizations`: ../interpreter-optimizations.html#lookup-method-call-method diff --git a/pypy/doc/config/objspace.opcodes.txt b/pypy/doc/config/objspace.opcodes.txt deleted file mode 100644 --- a/pypy/doc/config/objspace.opcodes.txt +++ /dev/null @@ -1,1 +0,0 @@ -.. intentionally empty diff --git a/pypy/doc/cppyy.rst b/pypy/doc/cppyy.rst --- a/pypy/doc/cppyy.rst +++ b/pypy/doc/cppyy.rst @@ -83,7 +83,7 @@ the selection of scientific software) will also work for a build with the builtin backend. -.. _`download`: http://cern.ch/wlav/reflex-2013-04-23.tar.bz2 +.. _`download`: http://cern.ch/wlav/reflex-2013-08-14.tar.bz2 .. _`ROOT`: http://root.cern.ch/ Besides Reflex, you probably need a version of `gccxml`_ installed, which is @@ -98,8 +98,8 @@ To install the standalone version of Reflex, after download:: - $ tar jxf reflex-2013-04-23.tar.bz2 - $ cd reflex-2013-04-23 + $ tar jxf reflex-2013-08-14.tar.bz2 + $ cd reflex-2013-08-14 $ ./build/autogen $ ./configure $ make && make install diff --git a/pypy/doc/faq.rst b/pypy/doc/faq.rst --- a/pypy/doc/faq.rst +++ b/pypy/doc/faq.rst @@ -356,7 +356,7 @@ attempt to point newcomers at existing alternatives, which are more mainstream and where they will get help from many people.* - *If anybody seriously wants to promote RPython anyway, he is welcome + *If anybody seriously wants to promote RPython anyway, they are welcome to: we won't actively resist such a plan. There are a lot of things that could be done to make RPython a better Java-ish language for example, starting with supporting non-GIL-based multithreading, but we @@ -396,8 +396,8 @@ patch the generated machine code. So the position of the core PyPy developers is that if anyone wants to -make an N+1'th attempt with LLVM, he is welcome, and he will receive a -bit of help on the IRC channel, but he is left with the burden of proof +make an N+1'th attempt with LLVM, they are welcome, and will be happy to +provide help in the IRC channel, but they are left with the burden of proof that it works. ---------------------- 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 @@ -57,6 +57,12 @@ zlib-devel bzip2-devel ncurses-devel expat-devel \ openssl-devel gc-devel python-sphinx python-greenlet + On SLES11: + + $ sudo zypper install gcc make python-devel pkg-config \ + zlib-devel libopenssl-devel libbz2-devel sqlite3-devel \ + libexpat-devel libffi-devel python-curses + The above command lines are split with continuation characters, giving the necessary dependencies first, then the optional ones. * ``pkg-config`` (to help us locate libffi files) 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 @@ -198,9 +198,6 @@ if it is not None, then it is considered to be an additional first argument in the call to the *im_func* object from the stack. -You can enable this feature with the :config:`objspace.opcodes.CALL_METHOD` -option. - .. more here? Overall Effects diff --git a/pypy/doc/jit/index.rst b/pypy/doc/jit/index.rst --- a/pypy/doc/jit/index.rst +++ b/pypy/doc/jit/index.rst @@ -23,7 +23,10 @@ - Hooks_ debugging facilities available to a python programmer +- Virtualizable_ how virtualizables work and what they are (in other words how + to make frames more efficient). .. _Overview: overview.html .. _Notes: pyjitpl5.html .. _Hooks: ../jit-hooks.html +.. _Virtualizable: virtualizable.html diff --git a/pypy/doc/jit/virtualizable.rst b/pypy/doc/jit/virtualizable.rst new file mode 100644 --- /dev/null +++ b/pypy/doc/jit/virtualizable.rst @@ -0,0 +1,60 @@ + +Virtualizables +============== + +**Note:** this document does not have a proper introduction as to how +to understand the basics. We should write some. If you happen to be here +and you're missing context, feel free to pester us on IRC. + +Problem description +------------------- + +The JIT is very good at making sure some objects are never allocated if they +don't escape from the trace. Such objects are called ``virtuals``. However, +if we're dealing with frames, virtuals are often not good enough. Frames +can escape and they can also be allocated already at the moment we enter the +JIT. In such cases we need some extra object that can still be optimized away, +despite existing on the heap. + +Solution +-------- + +We introduce virtualizables. They're objects that exist on the heap, but their +fields are not always in sync with whatever happens in the assembler. One +example is that virtualizable fields can store virtual objects without +forcing them. This is very useful for frames. Declaring an object to be +virtualizable works like this: + + class Frame(object): + _virtualizable_ = ['locals[*]', 'stackdepth'] + +And we use them in ``JitDriver`` like this:: + + jitdriver = JitDriver(greens=[], reds=['frame'], virtualizables=['frame']) + +This declaration means that ``stackdepth`` is a virtualizable **field**, while +``locals`` is a virtualizable **array** (a list stored on a virtualizable). +There are various rules about using virtualizables, especially using +virtualizable arrays that can be very confusing. Those will usually end +up with a compile-time error (as opposed to strange behavior). The rules are: + +* Each array access must be with a known positive index that cannot raise + an ``IndexError``. Using ``no = jit.hint(no, promote=True)`` might be useful + to get a constant-number access. This is only safe if the index is actually + constant or changing rarely within the context of the user's code. + +* If you initialize a new virtualizable in the JIT, it has to be done like this + (for example if we're in ``Frame.__init__``):: + + self = hint(self, access_directly=True, fresh_virtualizable=True) + + that way you can populate the fields directly. + +* If you use virtualizable outside of the JIT – it's very expensive and + sometimes aborts tracing. Consider it carefully as to how do it only for + debugging purposes and not every time (e.g. ``sys._getframe`` call). + +* If you have something equivalent of a Python generator, where the + virtualizable survives for longer, you want to force it before returning. + It's better to do it that way than by an external call some time later. + It's done using ``jit.hint(frame, force_virtualizable=True)`` diff --git a/pypy/doc/tool/makecontributor.py b/pypy/doc/tool/makecontributor.py --- a/pypy/doc/tool/makecontributor.py +++ b/pypy/doc/tool/makecontributor.py @@ -60,6 +60,11 @@ 'Roberto De Ioris': ['roberto at mrspurr'], 'Sven Hager': ['hager'], 'Tomo Cocoa': ['cocoatomo'], + 'Romain Guillebert': ['rguillebert', 'rguillbert', 'romain', 'Guillebert Romain'], + 'Ronan Lamy': ['ronan'], + 'Edd Barrett': ['edd'], + 'Manuel Jacob': ['mjacob'], + 'Rami Chowdhury': ['necaris'], } alias_map = {} @@ -80,7 +85,8 @@ if not match: return set() ignore_words = ['around', 'consulting', 'yesterday', 'for a bit', 'thanks', - 'in-progress', 'bits of', 'even a little', 'floating',] + 'in-progress', 'bits of', 'even a little', 'floating', + 'a bit', 'reviewing'] sep_words = ['and', ';', '+', '/', 'with special by'] nicknames = match.group(1) for word in ignore_words: @@ -119,7 +125,7 @@ ## print '%5d %s' % (n, name) ## else: ## print name - + items = authors_count.items() items.sort(key=operator.itemgetter(1), reverse=True) for name, n in items: 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 @@ -5,6 +5,11 @@ .. this is a revision shortly after release-2.1-beta .. startrev: 4eb52818e7c0 +.. branch: sanitise_bytecode_dispatch +Make PyPy's bytecode dispatcher easy to read, and less reliant on RPython +magic. There is no functional change, though the removal of dead code leads +to many fewer tests to execute. + .. branch: fastjson Fast json decoder written in RPython, about 3-4x faster than the pure Python decoder which comes with the stdlib @@ -62,3 +67,33 @@ No longer delegate numpy string_ methods to space.StringObject, in numpy this works by kind of by accident. Support for merging the refactor-str-types branch + +.. branch: kill-typesystem +Remove the "type system" abstraction, now that there is only ever one kind of +type system used. + +.. branch: kill-gen-store-back-in +Kills gen_store_back_in_virtualizable - should improve non-inlined calls by +a bit + +.. branch: dotviewer-linewidth +.. branch: reflex-support +.. branch: numpypy-inplace-op +.. branch: rewritten-loop-logging +.. branch: no-release-gil +.. branch: safe-win-mmap +.. branch: boolean-indexing-cleanup + +.. branch: nobold-backtrace +Work on improving UnionError messages and stack trace displays. + +.. branch: improve-errors-again +More improvements and refactorings of error messages. + +.. branch: improve-errors-again2 +Unbreak tests in rlib. + +.. branch: less-stringly-ops +Use subclasses of SpaceOperation instead of SpaceOperator objects. +Random cleanups in flowspace. + diff --git a/pypy/doc/windows.rst b/pypy/doc/windows.rst --- a/pypy/doc/windows.rst +++ b/pypy/doc/windows.rst @@ -6,6 +6,10 @@ The following text gives some hints about how to translate the PyPy interpreter. +PyPy supports only being translated as a 32bit program, even on +64bit Windows. See at the end of this page for what is missing +for a full 64bit translation. + To build pypy-c you need a C compiler. Microsoft Visual Studio is preferred, but can also use the mingw32 port of gcc. @@ -63,7 +67,7 @@ INCLUDE, LIB and PATH (for DLLs) environment variables appropriately. Abridged method (for -Ojit builds using Visual Studio 2008) -~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ Download the versions of all the external packages from https://bitbucket.org/pypy/pypy/downloads/local.zip @@ -112,13 +116,14 @@ nmake -f makefile.msc The sqlite3 database library -~~~~~~~~~~~~~~~~~~~~ +~~~~~~~~~~~~~~~~~~~~~~~~~~~~ Download http://www.sqlite.org/2013/sqlite-amalgamation-3071601.zip and extract it into a directory under the base directory. Also get http://www.sqlite.org/2013/sqlite-dll-win32-x86-3071601.zip and extract the dll into the bin directory, and the sqlite3.def into the sources directory. Now build the import library so cffi can use the header and dll:: + lib /DEF:sqlite3.def" /OUT:sqlite3.lib" copy sqlite3.lib path\to\libs @@ -206,8 +211,86 @@ March 2012, --cc is not a valid option for pytest.py. However if you set an environment variable CC to the compliter exe, testing will use it. -.. _'mingw32 build': http://sourceforge.net/projects/mingw-w64/files/Toolchains%20targetting%20Win32/Automated%20Builds +.. _`mingw32 build`: http://sourceforge.net/projects/mingw-w64/files/Toolchains%20targetting%20Win32/Automated%20Builds .. _`mingw64 build`: http://sourceforge.net/projects/mingw-w64/files/Toolchains%20targetting%20Win64/Automated%20Builds .. _`msys for mingw`: http://sourceforge.net/projects/mingw-w64/files/External%20binary%20packages%20%28Win64%20hosted%29/MSYS%20%2832-bit%29 .. _`libffi source files`: http://sourceware.org/libffi/ .. _`RPython translation toolchain`: translation.html + + +What is missing for a full 64-bit translation +--------------------------------------------- + +The main blocker is that we assume that the integer type of RPython is +large enough to (occasionally) contain a pointer value cast to an +integer. The simplest fix is to make sure that it is so, but it will +give the following incompatibility between CPython and PyPy on Win64: + +CPython: ``sys.maxint == 2**32-1, sys.maxsize == 2**64-1`` + +PyPy: ``sys.maxint == sys.maxsize == 2**64-1`` + +...and, correspondingly, PyPy supports ints up to the larger value of +sys.maxint before they are converted to ``long``. The first decision +that someone needs to make is if this incompatibility is reasonable. + +Assuming that it is, the first thing to do is probably to hack *CPython* +until it fits this model: replace the field in PyIntObject with a ``long +long`` field, and change the value of ``sys.maxint``. This might just +work, even if half-brokenly: I'm sure you can crash it because of the +precision loss that undoubtedly occurs everywhere, but try not to. :-) + +Such a hacked CPython is what you'll use in the next steps. We'll call +it CPython64/64. + +It is probably not too much work if the goal is only to get a translated +PyPy executable, and to run all tests before transaction. But you need +to start somewhere, and you should start with some tests in +rpython/translator/c/test/, like ``test_standalone.py`` and +``test_newgc.py``: try to have them pass on top of CPython64/64. + +Keep in mind that this runs small translations, and some details may go +wrong. The most obvious one is to check that it produces C files that +use the integer type ``Signed`` --- but what is ``Signed`` defined to? +It should be equal to ``long`` on every other platforms, but on Win64 it +should be something like ``long long``. + +What is more generally needed is to review all the C files in +rpython/translator/c/src for the word ``long``, because this means a +32-bit integer even on Win64. Replace it with ``Signed`` most of the +times. You can replace one with the other without breaking anything on +any other platform, so feel free to. + +Then, these two C types have corresponding RPython types: ``rffi.LONG`` +and ``lltype.Signed`` respectively. The first should really correspond +to the C ``long``. Add tests that check that integers casted to one +type or the other really have 32 and 64 bits respectively, on Win64. + +Once these basic tests work, you need to review ``rpython/rlib/`` for +usages of ``rffi.LONG`` versus ``lltype.Signed``. The goal would be to +fix some more ``LONG-versus-Signed`` issues, by fixing the tests --- as +always run on top of CPython64/64. Note that there was some early work +done in ``rpython/rlib/rarithmetic`` with the goal of running all the +tests on Win64 on the regular CPython, but I think by now that it's a +bad idea. Look only at CPython64/64. + +The major intermediate goal is to get a translation of PyPy with ``-O2`` +with a minimal set of modules, starting with ``--no-allworkingmodules``; +you need to use CPython64/64 to run this translation too. Check +carefully the warnings of the C compiler at the end. I think that MSVC +is "nice" in the sense that by default a lot of mismatches of integer +sizes are reported as warnings. + +Then you need to review ``pypy/module/*/`` for ``LONG-versus-Signed`` +issues. At some time during this review, we get a working translated +PyPy on Windows 64 that includes all ``--translationmodules``, i.e. +everything needed to run translations. When we are there, the hacked +CPython64/64 becomes much less important, because we can run future +translations on top of this translated PyPy. As soon as we get there, +please *distribute* the translated PyPy. It's an essential component +for anyone else that wants to work on Win64! We end up with a strange +kind of dependency --- we need a translated PyPy in order to translate a +PyPy ---, but I believe it's ok here, as Windows executables are +supposed to never be broken by newer versions of Windows. + +Happy hacking :-) 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 @@ -119,13 +119,12 @@ except: try: stderr = sys.stderr - except AttributeError: - pass # too bad - else: print >> stderr, 'Error calling sys.excepthook:' originalexcepthook(*sys.exc_info()) print >> stderr print >> stderr, 'Original exception was:' + except: + pass # too bad # we only get here if sys.excepthook didn't do its job originalexcepthook(etype, evalue, etraceback) 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 @@ -982,9 +982,8 @@ return self._call_has_no_star_args(call) and not call.keywords def _optimize_method_call(self, call): - if not self.space.config.objspace.opcodes.CALL_METHOD or \ - not self._call_has_no_star_args(call) or \ - not isinstance(call.func, ast.Attribute): + if not self._call_has_no_star_args(call) or \ + not isinstance(call.func, ast.Attribute): return False attr_lookup = call.func assert isinstance(attr_lookup, ast.Attribute) diff --git a/pypy/interpreter/baseobjspace.py b/pypy/interpreter/baseobjspace.py --- a/pypy/interpreter/baseobjspace.py +++ b/pypy/interpreter/baseobjspace.py @@ -77,12 +77,12 @@ raise NotImplementedError("only for interp-level user subclasses " "from typedef.py") - def getname(self, space, default='?'): + def getname(self, space): try: return space.str_w(space.getattr(self, space.wrap('__name__'))) except OperationError, e: if e.match(space, space.w_TypeError) or e.match(space, space.w_AttributeError): - return default + return '?' raise def getaddrstring(self, space): diff --git a/pypy/interpreter/buffer.py b/pypy/interpreter/buffer.py --- a/pypy/interpreter/buffer.py +++ b/pypy/interpreter/buffer.py @@ -19,7 +19,7 @@ from pypy.interpreter.typedef import TypeDef from pypy.interpreter.gateway import interp2app, unwrap_spec from pypy.interpreter.error import OperationError -from rpython.rlib.objectmodel import compute_hash +from rpython.rlib.objectmodel import compute_hash, import_from_mixin from rpython.rlib.rstring import StringBuilder @@ -272,8 +272,6 @@ # ____________________________________________________________ class SubBufferMixin(object): - _mixin_ = True - def __init__(self, buffer, offset, size): self.buffer = buffer self.offset = offset @@ -297,10 +295,11 @@ # out of bounds return self.buffer.getslice(self.offset + start, self.offset + stop, step, size) -class SubBuffer(SubBufferMixin, Buffer): - pass +class SubBuffer(Buffer): + import_from_mixin(SubBufferMixin) -class RWSubBuffer(SubBufferMixin, RWBuffer): +class RWSubBuffer(RWBuffer): + import_from_mixin(SubBufferMixin) def setitem(self, index, char): self.buffer.setitem(self.offset + index, char) diff --git a/pypy/interpreter/function.py b/pypy/interpreter/function.py --- a/pypy/interpreter/function.py +++ b/pypy/interpreter/function.py @@ -482,17 +482,16 @@ space.abstract_isinstance_w(w_firstarg, self.w_class)): pass # ok else: - clsdescr = self.w_class.getname(space, "") - if clsdescr: + clsdescr = self.w_class.getname(space) + if clsdescr and clsdescr != '?': clsdescr += " instance" else: clsdescr = "instance" if w_firstarg is None: instdescr = "nothing" else: - instname = space.abstract_getclass(w_firstarg).getname(space, - "") - if instname: + instname = space.abstract_getclass(w_firstarg).getname(space) + if instname and instname != '?': instdescr = instname + " instance" else: instdescr = "instance" diff --git a/pypy/interpreter/pycode.py b/pypy/interpreter/pycode.py --- a/pypy/interpreter/pycode.py +++ b/pypy/interpreter/pycode.py @@ -251,8 +251,10 @@ tuple(self.co_cellvars)) def exec_host_bytecode(self, w_globals, w_locals): - from pypy.interpreter.pyframe import CPythonFrame - frame = CPythonFrame(self.space, self, w_globals, None) + if sys.version_info < (2, 7): + raise Exception("PyPy no longer supports Python 2.6 or lower") + from pypy.interpreter.pyframe import PyFrame + frame = self.space.FrameClass(self.space, self, w_globals, None) frame.setdictscope(w_locals) return frame.run() diff --git a/pypy/interpreter/pyframe.py b/pypy/interpreter/pyframe.py --- a/pypy/interpreter/pyframe.py +++ b/pypy/interpreter/pyframe.py @@ -52,7 +52,7 @@ def __init__(self, space, code, w_globals, outer_func): if not we_are_translated(): - assert type(self) in (space.FrameClass, CPythonFrame), ( + assert type(self) == space.FrameClass, ( "use space.FrameClass(), not directly PyFrame()") self = hint(self, access_directly=True, fresh_virtualizable=True) assert isinstance(code, pycode.PyCode) @@ -123,8 +123,8 @@ # CO_OPTIMIZED: no locals dict needed at all # NB: this method is overridden in nestedscope.py flags = code.co_flags - if flags & pycode.CO_OPTIMIZED: - return + if flags & pycode.CO_OPTIMIZED: + return if flags & pycode.CO_NEWLOCALS: self.w_locals = self.space.newdict(module=True) else: @@ -176,9 +176,10 @@ executioncontext.return_trace(self, self.space.w_None) raise 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 + # it used to say self.last_exception = None + # this is now done by the code in pypyjit module + # since we don't want to invalidate the virtualizable + # for no good reason got_exception = False finally: executioncontext.leave(self, w_exitvalue, got_exception) @@ -260,7 +261,7 @@ break w_value = self.peekvalue(delta) self.pushvalue(w_value) - + def peekvalue(self, index_from_top=0): # NOTE: top of the stack is peekvalue(0). # Contrast this with CPython where it's PEEK(-1). @@ -330,7 +331,7 @@ nlocals = self.pycode.co_nlocals values_w = self.locals_stack_w[nlocals:self.valuestackdepth] w_valuestack = maker.slp_into_tuple_with_nulls(space, values_w) - + w_blockstack = nt([block._get_state_(space) for block in self.get_blocklist()]) w_fastlocals = maker.slp_into_tuple_with_nulls( space, self.locals_stack_w[:nlocals]) @@ -340,7 +341,7 @@ else: w_exc_value = self.last_exception.get_w_value(space) w_tb = w(self.last_exception.get_traceback()) - + tup_state = [ w(self.f_backref()), w(self.get_builtin()), @@ -355,7 +356,7 @@ w(f_lineno), w_fastlocals, space.w_None, #XXX placeholder for f_locals - + #f_restricted requires no additional data! space.w_None, ## self.w_f_trace, ignore for now @@ -389,7 +390,7 @@ ncellvars = len(pycode.co_cellvars) cellvars = cells[:ncellvars] closure = cells[ncellvars:] - + # do not use the instance's __init__ but the base's, because we set # everything like cells from here # XXX hack @@ -476,7 +477,7 @@ ### line numbers ### - def fget_f_lineno(self, space): + def fget_f_lineno(self, space): "Returns the line number of the instruction currently being executed." if self.w_f_trace is None: return space.wrap(self.get_last_lineno()) @@ -490,7 +491,7 @@ except OperationError, e: raise OperationError(space.w_ValueError, space.wrap("lineno must be an integer")) - + if self.w_f_trace is None: raise OperationError(space.w_ValueError, space.wrap("f_lineno can only be set by a trace function.")) @@ -522,7 +523,7 @@ if ord(code[new_lasti]) in (DUP_TOP, POP_TOP): raise OperationError(space.w_ValueError, space.wrap("can't jump to 'except' line as there's no exception")) - + # Don't jump into or out of a finally block. f_lasti_setup_addr = -1 new_lasti_setup_addr = -1 @@ -553,12 +554,12 @@ if addr == self.last_instr: f_lasti_setup_addr = setup_addr break - + if op >= HAVE_ARGUMENT: addr += 3 else: addr += 1 - + assert len(blockstack) == 0 if new_lasti_setup_addr != f_lasti_setup_addr: @@ -609,10 +610,10 @@ block = self.pop_block() block.cleanup(self) f_iblock -= 1 - + self.f_lineno = new_lineno self.last_instr = new_lasti - + def get_last_lineno(self): "Returns the line number of the instruction currently being executed." return pytraceback.offset2lineno(self.pycode, self.last_instr) @@ -638,8 +639,8 @@ self.f_lineno = self.get_last_lineno() space.frame_trace_action.fire() - def fdel_f_trace(self, space): - self.w_f_trace = None + def fdel_f_trace(self, space): + self.w_f_trace = None def fget_f_exc_type(self, space): if self.last_exception is not None: @@ -649,7 +650,7 @@ if f is not None: return f.last_exception.w_type return space.w_None - + def fget_f_exc_value(self, space): if self.last_exception is not None: f = self.f_backref() @@ -667,23 +668,12 @@ if f is not None: return space.wrap(f.last_exception.get_traceback()) return space.w_None - + def fget_f_restricted(self, space): if space.config.objspace.honor__builtins__: return space.wrap(self.builtin is not space.builtin) return space.w_False -class CPythonFrame(PyFrame): - """ - Execution of host (CPython) opcodes. - """ - - bytecode_spec = host_bytecode_spec - opcode_method_names = host_bytecode_spec.method_names - opcodedesc = host_bytecode_spec.opcodedesc - opdescmap = host_bytecode_spec.opdescmap - HAVE_ARGUMENT = host_bytecode_spec.HAVE_ARGUMENT - # ____________________________________________________________ diff --git a/pypy/interpreter/pyopcode.py b/pypy/interpreter/pyopcode.py --- a/pypy/interpreter/pyopcode.py +++ b/pypy/interpreter/pyopcode.py @@ -13,10 +13,8 @@ from rpython.rlib.objectmodel import we_are_translated from rpython.rlib import jit, rstackovf from rpython.rlib.rarithmetic import r_uint, intmask -from rpython.rlib.unroll import unrolling_iterable from rpython.rlib.debug import check_nonneg -from pypy.tool.stdlib_opcode import (bytecode_spec, - unrolling_all_opcode_descs) +from pypy.tool.stdlib_opcode import bytecode_spec def unaryoperation(operationname): """NOT_RPYTHON""" @@ -41,34 +39,14 @@ return func_with_new_name(opimpl, "opcode_impl_for_%s" % operationname) -compare_dispatch_table = [ - "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_dispatch_table)) - +opcodedesc = bytecode_spec.opcodedesc +HAVE_ARGUMENT = bytecode_spec.HAVE_ARGUMENT class __extend__(pyframe.PyFrame): """A PyFrame that knows about interpretation of standard Python opcodes minus the ones related to nested scopes.""" - bytecode_spec = bytecode_spec - opcode_method_names = bytecode_spec.method_names - opcodedesc = bytecode_spec.opcodedesc - opdescmap = bytecode_spec.opdescmap - HAVE_ARGUMENT = bytecode_spec.HAVE_ARGUMENT - ### opcode dispatch ### def dispatch(self, pycode, next_instr, ec): @@ -170,7 +148,7 @@ opcode = ord(co_code[next_instr]) next_instr += 1 - if opcode >= self.HAVE_ARGUMENT: + if opcode >= HAVE_ARGUMENT: lo = ord(co_code[next_instr]) hi = ord(co_code[next_instr+1]) next_instr += 2 @@ -180,19 +158,18 @@ # note: the structure of the code here is such that it makes # (after translation) a big "if/elif" chain, which is then - # turned into a switch(). It starts here: even if the first - # one is not an "if" but a "while" the effect is the same. + # turned into a switch(). - while opcode == self.opcodedesc.EXTENDED_ARG.index: + while opcode == opcodedesc.EXTENDED_ARG.index: opcode = ord(co_code[next_instr]) - if opcode < self.HAVE_ARGUMENT: + if opcode < HAVE_ARGUMENT: raise BytecodeCorruption lo = ord(co_code[next_instr+1]) hi = ord(co_code[next_instr+2]) next_instr += 3 oparg = (oparg * 65536) | (hi * 256) | lo - if opcode == self.opcodedesc.RETURN_VALUE.index: + if opcode == opcodedesc.RETURN_VALUE.index: w_returnvalue = self.popvalue() block = self.unrollstack(SReturnValue.kind) if block is None: @@ -202,8 +179,7 @@ unroller = SReturnValue(w_returnvalue) next_instr = block.handle(self, unroller) return next_instr # now inside a 'finally' block - - if opcode == self.opcodedesc.END_FINALLY.index: + elif opcode == opcodedesc.END_FINALLY.index: unroller = self.end_finally() if isinstance(unroller, SuspendedUnroller): # go on unrolling the stack @@ -215,49 +191,248 @@ else: next_instr = block.handle(self, unroller) return next_instr - - if opcode == self.opcodedesc.JUMP_ABSOLUTE.index: + elif opcode == opcodedesc.JUMP_ABSOLUTE.index: return self.jump_absolute(oparg, ec) - - if we_are_translated(): - for opdesc in unrolling_all_opcode_descs: - # static checks to skip this whole case if necessary - if opdesc.bytecode_spec is not self.bytecode_spec: - continue - if not opdesc.is_enabled(space): - continue - if opdesc.methodname in ( - 'EXTENDED_ARG', 'RETURN_VALUE', - 'END_FINALLY', 'JUMP_ABSOLUTE'): - continue # opcodes implemented above - - # the following "if" is part of the big switch described - # above. - if opcode == opdesc.index: - # dispatch to the opcode method - meth = getattr(self, opdesc.methodname) - res = meth(oparg, next_instr) - # !! warning, for the annotator the next line is not - # comparing an int and None - you can't do that. - # Instead, it's constant-folded to either True or False - if res is not None: - next_instr = res - break - else: - self.MISSING_OPCODE(oparg, next_instr) - - else: # when we are not translated, a list lookup is much faster - methodname = self.opcode_method_names[opcode] - try: - meth = getattr(self, methodname) - except AttributeError: - raise BytecodeCorruption("unimplemented opcode, ofs=%d, " - "code=%d, name=%s" % - (self.last_instr, opcode, - methodname)) - res = meth(oparg, next_instr) - if res is not None: - next_instr = res + elif opcode == opcodedesc.BREAK_LOOP.index: + next_instr = self.BREAK_LOOP(oparg, next_instr) + elif opcode == opcodedesc.CONTINUE_LOOP.index: + next_instr = self.CONTINUE_LOOP(oparg, next_instr) + elif opcode == opcodedesc.FOR_ITER.index: + next_instr = self.FOR_ITER(oparg, next_instr) + elif opcode == opcodedesc.JUMP_FORWARD.index: + next_instr = self.JUMP_FORWARD(oparg, next_instr) + elif opcode == opcodedesc.JUMP_IF_FALSE_OR_POP.index: + next_instr = self.JUMP_IF_FALSE_OR_POP(oparg, next_instr) + elif opcode == opcodedesc.JUMP_IF_NOT_DEBUG.index: + next_instr = self.JUMP_IF_NOT_DEBUG(oparg, next_instr) + elif opcode == opcodedesc.JUMP_IF_TRUE_OR_POP.index: + next_instr = self.JUMP_IF_TRUE_OR_POP(oparg, next_instr) + elif opcode == opcodedesc.POP_JUMP_IF_FALSE.index: + next_instr = self.POP_JUMP_IF_FALSE(oparg, next_instr) + elif opcode == opcodedesc.POP_JUMP_IF_TRUE.index: + next_instr = self.POP_JUMP_IF_TRUE(oparg, next_instr) + elif opcode == opcodedesc.BINARY_ADD.index: + self.BINARY_ADD(oparg, next_instr) + elif opcode == opcodedesc.BINARY_AND.index: + self.BINARY_AND(oparg, next_instr) + elif opcode == opcodedesc.BINARY_DIVIDE.index: + self.BINARY_DIVIDE(oparg, next_instr) + elif opcode == opcodedesc.BINARY_FLOOR_DIVIDE.index: + self.BINARY_FLOOR_DIVIDE(oparg, next_instr) + elif opcode == opcodedesc.BINARY_LSHIFT.index: + self.BINARY_LSHIFT(oparg, next_instr) + elif opcode == opcodedesc.BINARY_MODULO.index: + self.BINARY_MODULO(oparg, next_instr) + elif opcode == opcodedesc.BINARY_MULTIPLY.index: + self.BINARY_MULTIPLY(oparg, next_instr) + elif opcode == opcodedesc.BINARY_OR.index: + self.BINARY_OR(oparg, next_instr) + elif opcode == opcodedesc.BINARY_POWER.index: + self.BINARY_POWER(oparg, next_instr) + elif opcode == opcodedesc.BINARY_RSHIFT.index: + self.BINARY_RSHIFT(oparg, next_instr) + elif opcode == opcodedesc.BINARY_SUBSCR.index: + self.BINARY_SUBSCR(oparg, next_instr) + elif opcode == opcodedesc.BINARY_SUBTRACT.index: + self.BINARY_SUBTRACT(oparg, next_instr) + elif opcode == opcodedesc.BINARY_TRUE_DIVIDE.index: + self.BINARY_TRUE_DIVIDE(oparg, next_instr) + elif opcode == opcodedesc.BINARY_XOR.index: + self.BINARY_XOR(oparg, next_instr) + elif opcode == opcodedesc.BUILD_CLASS.index: + self.BUILD_CLASS(oparg, next_instr) + elif opcode == opcodedesc.BUILD_LIST.index: + self.BUILD_LIST(oparg, next_instr) + elif opcode == opcodedesc.BUILD_LIST_FROM_ARG.index: + self.BUILD_LIST_FROM_ARG(oparg, next_instr) + elif opcode == opcodedesc.BUILD_MAP.index: + self.BUILD_MAP(oparg, next_instr) + elif opcode == opcodedesc.BUILD_SET.index: + self.BUILD_SET(oparg, next_instr) + elif opcode == opcodedesc.BUILD_SLICE.index: + self.BUILD_SLICE(oparg, next_instr) + elif opcode == opcodedesc.BUILD_TUPLE.index: + self.BUILD_TUPLE(oparg, next_instr) + elif opcode == opcodedesc.CALL_FUNCTION.index: + self.CALL_FUNCTION(oparg, next_instr) + elif opcode == opcodedesc.CALL_FUNCTION_KW.index: + self.CALL_FUNCTION_KW(oparg, next_instr) + elif opcode == opcodedesc.CALL_FUNCTION_VAR.index: + self.CALL_FUNCTION_VAR(oparg, next_instr) + elif opcode == opcodedesc.CALL_FUNCTION_VAR_KW.index: + self.CALL_FUNCTION_VAR_KW(oparg, next_instr) + elif opcode == opcodedesc.CALL_METHOD.index: + self.CALL_METHOD(oparg, next_instr) + elif opcode == opcodedesc.COMPARE_OP.index: + self.COMPARE_OP(oparg, next_instr) + elif opcode == opcodedesc.DELETE_ATTR.index: + self.DELETE_ATTR(oparg, next_instr) + elif opcode == opcodedesc.DELETE_FAST.index: + self.DELETE_FAST(oparg, next_instr) + elif opcode == opcodedesc.DELETE_GLOBAL.index: + self.DELETE_GLOBAL(oparg, next_instr) + elif opcode == opcodedesc.DELETE_NAME.index: + self.DELETE_NAME(oparg, next_instr) + elif opcode == opcodedesc.DELETE_SLICE_0.index: + self.DELETE_SLICE_0(oparg, next_instr) + elif opcode == opcodedesc.DELETE_SLICE_1.index: + self.DELETE_SLICE_1(oparg, next_instr) + elif opcode == opcodedesc.DELETE_SLICE_2.index: + self.DELETE_SLICE_2(oparg, next_instr) + elif opcode == opcodedesc.DELETE_SLICE_3.index: + self.DELETE_SLICE_3(oparg, next_instr) + elif opcode == opcodedesc.DELETE_SUBSCR.index: + self.DELETE_SUBSCR(oparg, next_instr) + elif opcode == opcodedesc.DUP_TOP.index: + self.DUP_TOP(oparg, next_instr) + elif opcode == opcodedesc.DUP_TOPX.index: + self.DUP_TOPX(oparg, next_instr) + elif opcode == opcodedesc.EXEC_STMT.index: + self.EXEC_STMT(oparg, next_instr) + elif opcode == opcodedesc.GET_ITER.index: + self.GET_ITER(oparg, next_instr) + elif opcode == opcodedesc.IMPORT_FROM.index: + self.IMPORT_FROM(oparg, next_instr) + elif opcode == opcodedesc.IMPORT_NAME.index: + self.IMPORT_NAME(oparg, next_instr) + elif opcode == opcodedesc.IMPORT_STAR.index: + self.IMPORT_STAR(oparg, next_instr) + elif opcode == opcodedesc.INPLACE_ADD.index: + self.INPLACE_ADD(oparg, next_instr) + elif opcode == opcodedesc.INPLACE_AND.index: + self.INPLACE_AND(oparg, next_instr) + elif opcode == opcodedesc.INPLACE_DIVIDE.index: + self.INPLACE_DIVIDE(oparg, next_instr) + elif opcode == opcodedesc.INPLACE_FLOOR_DIVIDE.index: + self.INPLACE_FLOOR_DIVIDE(oparg, next_instr) + elif opcode == opcodedesc.INPLACE_LSHIFT.index: + self.INPLACE_LSHIFT(oparg, next_instr) + elif opcode == opcodedesc.INPLACE_MODULO.index: + self.INPLACE_MODULO(oparg, next_instr) + elif opcode == opcodedesc.INPLACE_MULTIPLY.index: + self.INPLACE_MULTIPLY(oparg, next_instr) + elif opcode == opcodedesc.INPLACE_OR.index: + self.INPLACE_OR(oparg, next_instr) + elif opcode == opcodedesc.INPLACE_POWER.index: + self.INPLACE_POWER(oparg, next_instr) + elif opcode == opcodedesc.INPLACE_RSHIFT.index: + self.INPLACE_RSHIFT(oparg, next_instr) + elif opcode == opcodedesc.INPLACE_SUBTRACT.index: + self.INPLACE_SUBTRACT(oparg, next_instr) + elif opcode == opcodedesc.INPLACE_TRUE_DIVIDE.index: + self.INPLACE_TRUE_DIVIDE(oparg, next_instr) + elif opcode == opcodedesc.INPLACE_XOR.index: + self.INPLACE_XOR(oparg, next_instr) + elif opcode == opcodedesc.LIST_APPEND.index: + self.LIST_APPEND(oparg, next_instr) + elif opcode == opcodedesc.LOAD_ATTR.index: + self.LOAD_ATTR(oparg, next_instr) + elif opcode == opcodedesc.LOAD_CLOSURE.index: + self.LOAD_CLOSURE(oparg, next_instr) + elif opcode == opcodedesc.LOAD_CONST.index: + self.LOAD_CONST(oparg, next_instr) + elif opcode == opcodedesc.LOAD_DEREF.index: + self.LOAD_DEREF(oparg, next_instr) + elif opcode == opcodedesc.LOAD_FAST.index: + self.LOAD_FAST(oparg, next_instr) + elif opcode == opcodedesc.LOAD_GLOBAL.index: + self.LOAD_GLOBAL(oparg, next_instr) + elif opcode == opcodedesc.LOAD_LOCALS.index: + self.LOAD_LOCALS(oparg, next_instr) + elif opcode == opcodedesc.LOAD_NAME.index: + self.LOAD_NAME(oparg, next_instr) + elif opcode == opcodedesc.LOOKUP_METHOD.index: + self.LOOKUP_METHOD(oparg, next_instr) + elif opcode == opcodedesc.MAKE_CLOSURE.index: + self.MAKE_CLOSURE(oparg, next_instr) + elif opcode == opcodedesc.MAKE_FUNCTION.index: + self.MAKE_FUNCTION(oparg, next_instr) + elif opcode == opcodedesc.MAP_ADD.index: + self.MAP_ADD(oparg, next_instr) + elif opcode == opcodedesc.NOP.index: + self.NOP(oparg, next_instr) + elif opcode == opcodedesc.POP_BLOCK.index: + self.POP_BLOCK(oparg, next_instr) + elif opcode == opcodedesc.POP_TOP.index: + self.POP_TOP(oparg, next_instr) + elif opcode == opcodedesc.PRINT_EXPR.index: + self.PRINT_EXPR(oparg, next_instr) + elif opcode == opcodedesc.PRINT_ITEM.index: + self.PRINT_ITEM(oparg, next_instr) + elif opcode == opcodedesc.PRINT_ITEM_TO.index: + self.PRINT_ITEM_TO(oparg, next_instr) + elif opcode == opcodedesc.PRINT_NEWLINE.index: + self.PRINT_NEWLINE(oparg, next_instr) + elif opcode == opcodedesc.PRINT_NEWLINE_TO.index: + self.PRINT_NEWLINE_TO(oparg, next_instr) + elif opcode == opcodedesc.RAISE_VARARGS.index: + self.RAISE_VARARGS(oparg, next_instr) + elif opcode == opcodedesc.ROT_FOUR.index: + self.ROT_FOUR(oparg, next_instr) + elif opcode == opcodedesc.ROT_THREE.index: + self.ROT_THREE(oparg, next_instr) + elif opcode == opcodedesc.ROT_TWO.index: + self.ROT_TWO(oparg, next_instr) + elif opcode == opcodedesc.SETUP_EXCEPT.index: + self.SETUP_EXCEPT(oparg, next_instr) + elif opcode == opcodedesc.SETUP_FINALLY.index: + self.SETUP_FINALLY(oparg, next_instr) + elif opcode == opcodedesc.SETUP_LOOP.index: + self.SETUP_LOOP(oparg, next_instr) + elif opcode == opcodedesc.SETUP_WITH.index: + self.SETUP_WITH(oparg, next_instr) + elif opcode == opcodedesc.SET_ADD.index: + self.SET_ADD(oparg, next_instr) + elif opcode == opcodedesc.SLICE_0.index: + self.SLICE_0(oparg, next_instr) + elif opcode == opcodedesc.SLICE_1.index: + self.SLICE_1(oparg, next_instr) + elif opcode == opcodedesc.SLICE_2.index: + self.SLICE_2(oparg, next_instr) + elif opcode == opcodedesc.SLICE_3.index: + self.SLICE_3(oparg, next_instr) + elif opcode == opcodedesc.STOP_CODE.index: + self.STOP_CODE(oparg, next_instr) + elif opcode == opcodedesc.STORE_ATTR.index: + self.STORE_ATTR(oparg, next_instr) + elif opcode == opcodedesc.STORE_DEREF.index: + self.STORE_DEREF(oparg, next_instr) + elif opcode == opcodedesc.STORE_FAST.index: + self.STORE_FAST(oparg, next_instr) + elif opcode == opcodedesc.STORE_GLOBAL.index: + self.STORE_GLOBAL(oparg, next_instr) + elif opcode == opcodedesc.STORE_MAP.index: + self.STORE_MAP(oparg, next_instr) + elif opcode == opcodedesc.STORE_NAME.index: + self.STORE_NAME(oparg, next_instr) + elif opcode == opcodedesc.STORE_SLICE_0.index: + self.STORE_SLICE_0(oparg, next_instr) + elif opcode == opcodedesc.STORE_SLICE_1.index: + self.STORE_SLICE_1(oparg, next_instr) + elif opcode == opcodedesc.STORE_SLICE_2.index: + self.STORE_SLICE_2(oparg, next_instr) + elif opcode == opcodedesc.STORE_SLICE_3.index: + self.STORE_SLICE_3(oparg, next_instr) + elif opcode == opcodedesc.STORE_SUBSCR.index: + self.STORE_SUBSCR(oparg, next_instr) + elif opcode == opcodedesc.UNARY_CONVERT.index: + self.UNARY_CONVERT(oparg, next_instr) + elif opcode == opcodedesc.UNARY_INVERT.index: + self.UNARY_INVERT(oparg, next_instr) + elif opcode == opcodedesc.UNARY_NEGATIVE.index: + self.UNARY_NEGATIVE(oparg, next_instr) + elif opcode == opcodedesc.UNARY_NOT.index: + self.UNARY_NOT(oparg, next_instr) + elif opcode == opcodedesc.UNARY_POSITIVE.index: + self.UNARY_POSITIVE(oparg, next_instr) + elif opcode == opcodedesc.UNPACK_SEQUENCE.index: + self.UNPACK_SEQUENCE(oparg, next_instr) + elif opcode == opcodedesc.WITH_CLEANUP.index: + self.WITH_CLEANUP(oparg, next_instr) + elif opcode == opcodedesc.YIELD_VALUE.index: + self.YIELD_VALUE(oparg, next_instr) + else: + self.MISSING_OPCODE(oparg, next_instr) if jit.we_are_jitted(): return next_instr @@ -733,36 +908,6 @@ self.pushvalue(w_value) LOAD_ATTR._always_inline_ = True - def cmp_lt(self, w_1, w_2): - return self.space.lt(w_1, w_2) - - def cmp_le(self, w_1, w_2): - return self.space.le(w_1, w_2) - - def cmp_eq(self, w_1, w_2): - return self.space.eq(w_1, w_2) - - def cmp_ne(self, w_1, w_2): - return self.space.ne(w_1, w_2) - - def cmp_gt(self, w_1, w_2): - return self.space.gt(w_1, w_2) - - def cmp_ge(self, w_1, w_2): - return self.space.ge(w_1, w_2) - - def cmp_in(self, w_1, w_2): - return self.space.contains(w_2, w_1) - - def cmp_not_in(self, w_1, w_2): - return self.space.not_(self.space.contains(w_2, w_1)) - - def cmp_is(self, w_1, w_2): - return self.space.is_(w_1, w_2) - - def cmp_is_not(self, w_1, w_2): - return self.space.not_(self.space.is_(w_1, w_2)) - From noreply at buildbot.pypy.org Thu Sep 19 20:27:24 2013 From: noreply at buildbot.pypy.org (mattip) Date: Thu, 19 Sep 2013 20:27:24 +0200 (CEST) Subject: [pypy-commit] pypy pypy-pyarray: fix merge Message-ID: <20130919182724.CDFE71C115D@cobra.cs.uni-duesseldorf.de> Author: Matti Picus Branch: pypy-pyarray Changeset: r67008:da74a3028891 Date: 2013-09-19 21:03 +0300 http://bitbucket.org/pypy/pypy/changeset/da74a3028891/ Log: fix 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 @@ -283,7 +283,7 @@ s = loop.count_all_true_concrete(self) box = index_type.itemtype.box nd = len(self.get_shape()) - w_res = W_NDimArray.from_shape(space, [s, nd], index_type) + w_res = W_NDimArray.from_shape(space, [s, nd], index_type) loop.nonzero(w_res, self, box) w_res = w_res.implementation.swapaxes(space, w_res, 0, 1) l_w = [w_res.descr_getitem(space, space.wrap(d)) for d in range(nd)] @@ -326,17 +326,18 @@ self.storage = storage def create_iter(self, shape=None, backward_broadcast=False, require_index=False): - if shape is not None and support.product(shape) > support.product(self.get_shape()): + if shape is not None and \ + support.product(shape) > support.product(self.get_shape()): r = calculate_broadcast_strides(self.get_strides(), self.get_backstrides(), self.get_shape(), shape, backward_broadcast) return iter.MultiDimViewIterator(self, self.dtype, self.start, r[0], r[1], shape) - + if not require_index: return iter.ConcreteArrayIterator(self) else: if len(self.get_shape()) == 1: - return iter.OneDimViewIterator(self, self.dtype, self.start, + return iter.OneDimViewIterator(self, self.dtype, self.start, self.get_strides(), self.get_shape()) else: return iter.MultiDimViewIterator(self, self.dtype, self.start, @@ -404,7 +405,8 @@ loop.fill(self, box.convert_to(self.dtype)) def create_iter(self, shape=None, backward_broadcast=False, require_index=False): - if shape is not None and ssupport.product(shape) > support.prodduct(self.get_shape()): + if shape is not None and \ + support.product(shape) > support.product(self.get_shape()): r = calculate_broadcast_strides(self.get_strides(), self.get_backstrides(), self.get_shape(), shape, 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 @@ -95,8 +95,7 @@ if idx.get_size() > self.get_size(): raise OperationError(space.w_ValueError, space.wrap("index out of range for array")) - idx_iter = idx.create_iter() - size = loop.count_all_true_iter(idx_iter, idx.get_shape(), idx.get_dtype()) + size = loop.count_all_true(idx) if size > val.get_size() and val.get_size() > 1: raise OperationError(space.w_ValueError, space.wrap("NumPy boolean array indexing assignment " "cannot assign %d input values to " From noreply at buildbot.pypy.org Thu Sep 19 23:03:39 2013 From: noreply at buildbot.pypy.org (mattip) Date: Thu, 19 Sep 2013 23:03:39 +0200 (CEST) Subject: [pypy-commit] pypy pypy-pyarray: test untested ndarrayobject.py functions Message-ID: <20130919210339.351221C115D@cobra.cs.uni-duesseldorf.de> Author: Matti Picus Branch: pypy-pyarray Changeset: r67010:1fa45adb9429 Date: 2013-09-19 22:57 +0300 http://bitbucket.org/pypy/pypy/changeset/1fa45adb9429/ Log: test untested ndarrayobject.py functions diff --git a/TODO.txt b/TODO.txt --- a/TODO.txt +++ b/TODO.txt @@ -3,8 +3,6 @@ - test "from numpypy import *" esp. get_include() - test all *.h files under pypy/module/cpyext/include/numpy -- make sure meaningful cpyext changes are tested: - copy_header_files() in api.py (changed) - all ndarrayobject.py (new) +- make sure copy_header_files() in api.py is used in package.py - test, implement use of __array_prepare__() - test, implement use of __array_wrap__() diff --git a/pypy/module/cpyext/ndarrayobject.py b/pypy/module/cpyext/ndarrayobject.py --- a/pypy/module/cpyext/ndarrayobject.py +++ b/pypy/module/cpyext/ndarrayobject.py @@ -171,17 +171,7 @@ @cpython_api([PyObject, Py_ssize_t, Py_ssize_t, Py_ssize_t], PyObject) def _PyArray_FromObject(space, w_obj, typenum, min_depth, max_depth): - if min_depth !=0 or max_depth != 0: - raise OperationError(space.w_NotImplementedError, space.wrap( - '_PyArray_FromObject called with not-implemented min_dpeth or max_depth argument')) - dtype = get_dtype_cache(space).dtypes_by_num[typenum] - w_array = convert_to_array(space, w_obj) - impl = w_array.implementation - if w_array.is_scalar(): - return W_NDimArray.new_scalar(space, dtype, impl.value) - else: - new_impl = impl.astype(space, dtype) - return wrap_impl(space, space.type(w_array), w_array, new_impl) + return _PyArray_FromAny(space, w_obj, typenum, min_depth, max_depth, NPY_BEHAVED); def get_shape_and_dtype(space, nd, dims, typenum): diff --git a/pypy/module/cpyext/test/test_ndarrayobject.py b/pypy/module/cpyext/test/test_ndarrayobject.py --- a/pypy/module/cpyext/test/test_ndarrayobject.py +++ b/pypy/module/cpyext/test/test_ndarrayobject.py @@ -51,6 +51,10 @@ a = array(space, [10, 5, 3]) assert api._PyArray_DIM(a, 1) == 5 + def test_STRIDE(self, space, api): + a = array(space, [10, 5, 3], ) + assert api._PyArray_STRIDE(a, 1) == a.implementation.get_strides()[1] + def test_SIZE(self, space, api): a = array(space, [10, 5, 3]) assert api._PyArray_SIZE(a) == 150 @@ -90,6 +94,13 @@ space.wrap(a), space.w_None, space.wrap(0), space.wrap(3), space.wrap(0), space.w_None) + def test_FromObject(self, space, api): + a = array(space, [10, 5, 3]) + assert api._PyArray_FromObject(a, NULL, 0, 0, 0, NULL) is a + self.raises(space, api, NotImplementedError, api._PyArray_FromObject, + space.wrap(a), space.w_None, space.wrap(0), + space.wrap(3), space.wrap(0), space.w_None) + def test_list_from_fixedptr(self, space, api): A = lltype.GcArray(lltype.Float) ptr = lltype.malloc(A, 3) @@ -184,6 +195,11 @@ ptr_r = rffi.cast(rffi.DOUBLEP, api._PyArray_DATA(res)) for i in range(150): assert ptr_r[i] == float(i) + res = api._PyArray_SimpleNewFromDataOwning(nd, ptr_s, num, ptr_a) + x = rffi.cast(rffi.DOUBLEP, ptr_a) + ptr_r = rffi.cast(rffi.DOUBLEP, api._PyArray_DATA(res)) + x[20] = -100. + assert ptr_r[20] == -100. def test_SimpleNewFromData_complex(self, space, api): a = array(space, [2]) From noreply at buildbot.pypy.org Thu Sep 19 23:03:40 2013 From: noreply at buildbot.pypy.org (mattip) Date: Thu, 19 Sep 2013 23:03:40 +0200 (CEST) Subject: [pypy-commit] pypy default: fix for failing test Message-ID: <20130919210340.6B0C21C14E8@cobra.cs.uni-duesseldorf.de> Author: Matti Picus Branch: Changeset: r67011:799a5addbfc5 Date: 2013-09-20 00:02 +0300 http://bitbucket.org/pypy/pypy/changeset/799a5addbfc5/ Log: fix for failing test 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 @@ -374,7 +374,7 @@ def setitem_filter(arr, index, value, size): arr_iter = arr.create_iter() - index_iter = index.create_iter(arr.get_shape()) + index_iter = index.create_iter(index.get_shape()) value_iter = value.create_iter([size]) shapelen = len(arr.get_shape()) index_dtype = index.get_dtype() From noreply at buildbot.pypy.org Thu Sep 19 23:03:38 2013 From: noreply at buildbot.pypy.org (mattip) Date: Thu, 19 Sep 2013 23:03:38 +0200 (CEST) Subject: [pypy-commit] pypy pypy-pyarray: add test for ndarrayobject.c, no error checking since numpy does not do error checking either Message-ID: <20130919210338.19FE71C02B1@cobra.cs.uni-duesseldorf.de> Author: Matti Picus Branch: pypy-pyarray Changeset: r67009:5352a97e55e8 Date: 2013-09-19 22:33 +0300 http://bitbucket.org/pypy/pypy/changeset/5352a97e55e8/ Log: add test for ndarrayobject.c, no error checking since numpy does not do error checking either diff --git a/TODO.txt b/TODO.txt --- a/TODO.txt +++ b/TODO.txt @@ -1,13 +1,9 @@ -Comments by antocuni, rguillebert -================================== - TODO list by mattip =================== - test "from numpypy import *" esp. get_include() - test all *.h files under pypy/module/cpyext/include/numpy - make sure meaningful cpyext changes are tested: - all ndarrayobject.c copy_header_files() in api.py (changed) all ndarrayobject.py (new) - test, implement use of __array_prepare__() diff --git a/pypy/module/cpyext/test/test_ndarrayobject.py b/pypy/module/cpyext/test/test_ndarrayobject.py --- a/pypy/module/cpyext/test/test_ndarrayobject.py +++ b/pypy/module/cpyext/test/test_ndarrayobject.py @@ -1,7 +1,7 @@ import py -from pypy.module.cpyext.pyobject import PyObject from pypy.module.cpyext.test.test_api import BaseApiTest +from pypy.module.cpyext.test.test_cpyext import AppTestCpythonExtensionBase from rpython.rtyper.lltypesystem import rffi, lltype from pypy.module.micronumpy.interp_numarray import W_NDimArray @@ -199,3 +199,42 @@ assert res.get_scalar_value().real == 3. assert res.get_scalar_value().imag == 4. +class AppTestCNumber(AppTestCpythonExtensionBase): + def test_ndarray_object_c(self): + mod = self.import_extension('foo', [ + ("test_simplenew", "METH_NOARGS", + ''' + npy_intp dims[2] ={2, 3}; + PyObject * obj = PyArray_SimpleNew(2, dims, 11); + return obj; + ''' + ), + ("test_fill", "METH_NOARGS", + ''' + npy_intp dims[2] ={2, 3}; + PyObject * obj = PyArray_SimpleNew(2, dims, 1); + PyArray_FILLWBYTE(obj, 42); + return obj; + ''' + ), + ("test_copy", "METH_NOARGS", + ''' + npy_intp dims1[2] ={2, 3}; + npy_intp dims2[2] ={3, 2}; + PyObject * obj1 = PyArray_ZEROS(2, dims1, 11, 0); + PyObject * obj2 = PyArray_ZEROS(2, dims2, 11, 0); + PyArray_FILLWBYTE(obj2, 42); + PyArray_CopyInto(obj2, obj1); + return obj2; + ''' + ), + ], prologue='#include ') + arr = mod.test_simplenew() + assert arr.shape == (2, 3) + assert arr.dtype.num == 11 #float32 dtype + arr = mod.test_fill() + assert arr.shape == (2, 3) + assert arr.dtype.num == 1 #int8 dtype + assert (arr == 42).all() + arr = mod.test_copy() + assert (arr == 0).all() From noreply at buildbot.pypy.org Fri Sep 20 08:36:34 2013 From: noreply at buildbot.pypy.org (wlav) Date: Fri, 20 Sep 2013 08:36:34 +0200 (CEST) Subject: [pypy-commit] pypy reflex-support: code convention fix Message-ID: <20130920063634.951CD1C30E4@cobra.cs.uni-duesseldorf.de> Author: Wim Lavrijsen Branch: reflex-support Changeset: r67016:52bbec630c1f Date: 2013-09-17 14:07 -0700 http://bitbucket.org/pypy/pypy/changeset/52bbec630c1f/ Log: code convention fix 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 @@ -482,7 +482,7 @@ def pygaus(x, par): arg1 = 0 - scale1 =0 + scale1 = 0 ddx = 0.01 if (par[2] != 0.0): From noreply at buildbot.pypy.org Fri Sep 20 08:36:27 2013 From: noreply at buildbot.pypy.org (wlav) Date: Fri, 20 Sep 2013 08:36:27 +0200 (CEST) Subject: [pypy-commit] pypy reflex-support: fix comment Message-ID: <20130920063627.E00D91C0209@cobra.cs.uni-duesseldorf.de> Author: Wim Lavrijsen Branch: reflex-support Changeset: r67012:74285b1995d3 Date: 2013-09-13 23:16 -0700 http://bitbucket.org/pypy/pypy/changeset/74285b1995d3/ Log: fix comment 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 @@ -1141,7 +1141,7 @@ do_cast=True, python_owns=False, is_ref=False, fresh=False): rawobject = rffi.cast(capi.C_OBJECT, rawobject) - # cast to actual cast if requested and possible + # cast to actual if requested and possible w_pycppclass = space.w_None if do_cast and rawobject: actual = capi.c_actual_class(space, cppclass, rawobject) From noreply at buildbot.pypy.org Fri Sep 20 08:36:35 2013 From: noreply at buildbot.pypy.org (wlav) Date: Fri, 20 Sep 2013 08:36:35 +0200 (CEST) Subject: [pypy-commit] pypy reflex-support: simplification Message-ID: <20130920063635.B771C1C0209@cobra.cs.uni-duesseldorf.de> Author: Wim Lavrijsen Branch: reflex-support Changeset: r67017:a5f2ba76c332 Date: 2013-09-17 14:08 -0700 http://bitbucket.org/pypy/pypy/changeset/a5f2ba76c332/ Log: simplification 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 @@ -1142,7 +1142,7 @@ rawobject = rffi.cast(capi.C_OBJECT, rawobject) # cast to actual if requested and possible - w_pycppclass = space.w_None + w_pycppclass = None if do_cast and rawobject: actual = capi.c_actual_class(space, cppclass, rawobject) if actual != cppclass.handle: @@ -1158,7 +1158,7 @@ # the variables are re-assigned yet) pass - if space.is_w(w_pycppclass, space.w_None): + if w_pycppclass is None: w_pycppclass = get_pythonized_cppclass(space, cppclass.handle) # try to recycle existing object if this one is not newly created 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 @@ -372,8 +372,6 @@ static inline G__value cppyy_call_T(cppyy_method_t method, cppyy_object_t self, int nargs, void* args) { - R__LOCKGUARD2(gCINTMutex); - G__param* libp = (G__param*)((char*)args - offsetof(G__param, para)); assert(libp->paran == nargs); fixup_args(libp); @@ -1009,7 +1007,7 @@ long cppyy_tfn_install(const char* funcname, int npar) { // make a new function placeholder known to CINT - static Long_t s_fid = (Long_t)cppyy_tfn_install; + static Long_t s_fid = (Long_t)cppyy_tfn_install; // ensures no user function lives there ++s_fid; const char* signature = "D - - 0 - - D - - 0 - -"; From noreply at buildbot.pypy.org Fri Sep 20 08:36:36 2013 From: noreply at buildbot.pypy.org (wlav) Date: Fri, 20 Sep 2013 08:36:36 +0200 (CEST) Subject: [pypy-commit] pypy reflex-support: by definition, temporary objects are not seen before Message-ID: <20130920063636.DB9441C0209@cobra.cs.uni-duesseldorf.de> Author: Wim Lavrijsen Branch: reflex-support Changeset: r67018:5514fa992ac6 Date: 2013-09-17 14:08 -0700 http://bitbucket.org/pypy/pypy/changeset/5514fa992ac6/ Log: by definition, temporary objects are not seen before 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 @@ -190,7 +190,7 @@ long_result = capi.c_call_o(space, cppmethod, cppthis, num_args, args, self.cppclass) ptr_result = rffi.cast(capi.C_OBJECT, long_result) return interp_cppyy.wrap_cppobject(space, ptr_result, self.cppclass, - do_cast=False, python_owns=True) + do_cast=False, python_owns=True, fresh=True) def execute_libffi(self, space, cif_descr, funcaddr, buffer): from pypy.module.cppyy.interp_cppyy import FastCallNotPossible From noreply at buildbot.pypy.org Fri Sep 20 08:36:31 2013 From: noreply at buildbot.pypy.org (wlav) Date: Fri, 20 Sep 2013 08:36:31 +0200 (CEST) Subject: [pypy-commit] pypy reflex-support: merge default into branch Message-ID: <20130920063631.0C0B51C1153@cobra.cs.uni-duesseldorf.de> Author: Wim Lavrijsen Branch: reflex-support Changeset: r67013:5b438999f8c4 Date: 2013-09-15 11:40 -0700 http://bitbucket.org/pypy/pypy/changeset/5b438999f8c4/ Log: merge default into branch diff too long, truncating to 2000 out of 4726 lines diff --git a/lib-python/2.7/argparse.py b/lib-python/2.7/argparse.py --- a/lib-python/2.7/argparse.py +++ b/lib-python/2.7/argparse.py @@ -1780,7 +1780,19 @@ # error if this argument is not allowed with other previously # seen arguments, assuming that actions that use the default # value don't really count as "present" - if argument_values is not action.default: + + # XXX PyPy bug-to-bug compatibility: "is" on primitive types + # is not consistent in CPython. We'll assume it is close + # enough for ints (which is true only for "small ints"), but + # for floats and longs and complexes we'll go for the option + # of forcing "is" to say False, like it usually does on + # CPython. A fix is pending on CPython trunk + # (http://bugs.python.org/issue18943) but that might change + # the details of the semantics and so not be applied to 2.7. + # See the line AA below. + + if (argument_values is not action.default or + type(argument_values) in (float, long, complex)): # AA seen_non_default_actions.add(action) for conflict_action in action_conflicts.get(action, []): if conflict_action in seen_non_default_actions: diff --git a/lib_pypy/_tkinter/__init__.py b/lib_pypy/_tkinter/__init__.py --- a/lib_pypy/_tkinter/__init__.py +++ b/lib_pypy/_tkinter/__init__.py @@ -22,6 +22,7 @@ READABLE = tklib.TCL_READABLE WRITABLE = tklib.TCL_WRITABLE EXCEPTION = tklib.TCL_EXCEPTION +DONT_WAIT = tklib.TCL_DONT_WAIT def create(screenName=None, baseName=None, className=None, interactive=False, wantobjects=False, wantTk=True, diff --git a/lib_pypy/_tkinter/app.py b/lib_pypy/_tkinter/app.py --- a/lib_pypy/_tkinter/app.py +++ b/lib_pypy/_tkinter/app.py @@ -4,7 +4,23 @@ from . import TclError from .tclobj import TclObject, FromObj, AsObj, TypeCache +import contextlib import sys +import threading +import time + + +class _DummyLock(object): + "A lock-like object that does not do anything" + def acquire(self): + pass + def release(self): + pass + def __enter__(self): + pass + def __exit__(self, *exc): + pass + def varname_converter(input): if isinstance(input, TclObject): @@ -37,17 +53,18 @@ def PythonCmd(clientData, interp, argc, argv): self = tkffi.from_handle(clientData) assert self.app.interp == interp - try: - args = [tkffi.string(arg) for arg in argv[1:argc]] - result = self.func(*args) - obj = AsObj(result) - tklib.Tcl_SetObjResult(interp, obj) - except: - self.app.errorInCmd = True - self.app.exc_info = sys.exc_info() - return tklib.TCL_ERROR - else: - return tklib.TCL_OK + with self.app._tcl_lock_released(): + try: + args = [tkffi.string(arg) for arg in argv[1:argc]] + result = self.func(*args) + obj = AsObj(result) + tklib.Tcl_SetObjResult(interp, obj) + except: + self.app.errorInCmd = True + self.app.exc_info = sys.exc_info() + return tklib.TCL_ERROR + else: + return tklib.TCL_OK @tkffi.callback("Tcl_CmdDeleteProc") def PythonCmdDelete(clientData): @@ -58,6 +75,8 @@ class TkApp(object): + _busywaitinterval = 0.02 # 20ms. + def __new__(cls, screenName, baseName, className, interactive, wantobjects, wantTk, sync, use): if not wantobjects: @@ -73,6 +92,12 @@ self.quitMainLoop = False self.errorInCmd = False + if not self.threaded: + # TCL is not thread-safe, calls needs to be serialized. + self._tcl_lock = threading.Lock() + else: + self._tcl_lock = _DummyLock() + self._typeCache = TypeCache() self._commands = {} @@ -133,6 +158,13 @@ if self.threaded and self.thread_id != tklib.Tcl_GetCurrentThread(): raise RuntimeError("Calling Tcl from different appartment") + @contextlib.contextmanager + def _tcl_lock_released(self): + "Context manager to temporarily release the tcl lock." + self._tcl_lock.release() + yield + self._tcl_lock.acquire() + def loadtk(self): # We want to guard against calling Tk_Init() multiple times err = tklib.Tcl_Eval(self.interp, "info exists tk_version") @@ -159,22 +191,25 @@ flags=tklib.TCL_LEAVE_ERR_MSG if global_only: flags |= tklib.TCL_GLOBAL_ONLY - res = tklib.Tcl_GetVar2Ex(self.interp, name1, name2, flags) - if not res: - self.raiseTclError() - assert self._wantobjects - return FromObj(self, res) + with self._tcl_lock: + res = tklib.Tcl_GetVar2Ex(self.interp, name1, name2, flags) + if not res: + self.raiseTclError() + assert self._wantobjects + return FromObj(self, res) def _setvar(self, name1, value, global_only=False): name1 = varname_converter(name1) + # XXX Acquire tcl lock??? newval = AsObj(value) flags=tklib.TCL_LEAVE_ERR_MSG if global_only: flags |= tklib.TCL_GLOBAL_ONLY - res = tklib.Tcl_SetVar2Ex(self.interp, name1, tkffi.NULL, - newval, flags) - if not res: - self.raiseTclError() + with self._tcl_lock: + res = tklib.Tcl_SetVar2Ex(self.interp, name1, tkffi.NULL, + newval, flags) + if not res: + self.raiseTclError() def _unsetvar(self, name1, name2=None, global_only=False): name1 = varname_converter(name1) @@ -183,9 +218,10 @@ flags=tklib.TCL_LEAVE_ERR_MSG if global_only: flags |= tklib.TCL_GLOBAL_ONLY - res = tklib.Tcl_UnsetVar2(self.interp, name1, name2, flags) - if res == tklib.TCL_ERROR: - self.raiseTclError() + with self._tcl_lock: + res = tklib.Tcl_UnsetVar2(self.interp, name1, name2, flags) + if res == tklib.TCL_ERROR: + self.raiseTclError() def getvar(self, name1, name2=None): return self._var_invoke(self._getvar, name1, name2) @@ -219,9 +255,10 @@ if self.threaded and self.thread_id != tklib.Tcl_GetCurrentThread(): raise NotImplementedError("Call from another thread") - res = tklib.Tcl_CreateCommand( - self.interp, cmdName, _CommandData.PythonCmd, - clientData, _CommandData.PythonCmdDelete) + with self._tcl_lock: + res = tklib.Tcl_CreateCommand( + self.interp, cmdName, _CommandData.PythonCmd, + clientData, _CommandData.PythonCmdDelete) if not res: raise TclError("can't create Tcl command") @@ -229,7 +266,8 @@ if self.threaded and self.thread_id != tklib.Tcl_GetCurrentThread(): raise NotImplementedError("Call from another thread") - res = tklib.Tcl_DeleteCommand(self.interp, cmdName) + with self._tcl_lock: + res = tklib.Tcl_DeleteCommand(self.interp, cmdName) if res == -1: raise TclError("can't delete Tcl command") @@ -256,11 +294,12 @@ tklib.Tcl_IncrRefCount(obj) objects[i] = obj - res = tklib.Tcl_EvalObjv(self.interp, argc, objects, flags) - if res == tklib.TCL_ERROR: - self.raiseTclError() - else: - result = self._callResult() + with self._tcl_lock: + res = tklib.Tcl_EvalObjv(self.interp, argc, objects, flags) + if res == tklib.TCL_ERROR: + self.raiseTclError() + else: + result = self._callResult() finally: for obj in objects: if obj: @@ -280,17 +319,19 @@ def eval(self, script): self._check_tcl_appartment() - res = tklib.Tcl_Eval(self.interp, script) - if res == tklib.TCL_ERROR: - self.raiseTclError() - return tkffi.string(tklib.Tcl_GetStringResult(self.interp)) + with self._tcl_lock: + res = tklib.Tcl_Eval(self.interp, script) + if res == tklib.TCL_ERROR: + self.raiseTclError() + return tkffi.string(tklib.Tcl_GetStringResult(self.interp)) def evalfile(self, filename): self._check_tcl_appartment() - res = tklib.Tcl_EvalFile(self.interp, filename) - if res == tklib.TCL_ERROR: - self.raiseTclError() - return tkffi.string(tklib.Tcl_GetStringResult(self.interp)) + with self._tcl_lock: + res = tklib.Tcl_EvalFile(self.interp, filename) + if res == tklib.TCL_ERROR: + self.raiseTclError() + return tkffi.string(tklib.Tcl_GetStringResult(self.interp)) def split(self, arg): if isinstance(arg, tuple): @@ -375,7 +416,10 @@ if self.threaded: result = tklib.Tcl_DoOneEvent(0) else: - raise NotImplementedError("TCL configured without threads") + with self._tcl_lock: + result = tklib.Tcl_DoOneEvent(tklib.TCL_DONT_WAIT) + if result == 0: + time.sleep(self._busywaitinterval) if result < 0: break diff --git a/lib_pypy/_tkinter/tklib.py b/lib_pypy/_tkinter/tklib.py --- a/lib_pypy/_tkinter/tklib.py +++ b/lib_pypy/_tkinter/tklib.py @@ -1,6 +1,7 @@ # C bindings with libtcl and libtk. from cffi import FFI +import sys tkffi = FFI() @@ -18,6 +19,8 @@ #define TCL_EVAL_DIRECT ... #define TCL_EVAL_GLOBAL ... +#define TCL_DONT_WAIT ... + typedef unsigned short Tcl_UniChar; typedef ... Tcl_Interp; typedef ...* Tcl_ThreadId; @@ -102,6 +105,17 @@ int Tk_GetNumMainWindows(); """) +# XXX find a better way to detect paths +# XXX pick up CPPFLAGS and LDFLAGS and add to these paths? +if sys.platform.startswith("openbsd"): + incdirs = ['/usr/local/include/tcl8.5', '/usr/local/include/tk8.5', '/usr/X11R6/include'] + linklibs = ['tk85', 'tcl85'] + libdirs = ['/usr/local/lib', '/usr/X11R6/lib'] +else: + incdirs=['/usr/include/tcl'] + linklibs=['tcl', 'tk'] + libdirs = [] + tklib = tkffi.verify(""" #include #include @@ -109,6 +123,7 @@ char *get_tk_version() { return TK_VERSION; } char *get_tcl_version() { return TCL_VERSION; } """, -include_dirs=['/usr/include/tcl'], -libraries=['tcl', 'tk'], +include_dirs=incdirs, +libraries=linklibs, +library_dirs = libdirs ) 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 @@ -80,6 +80,7 @@ .. branch: reflex-support .. branch: numpypy-inplace-op .. branch: rewritten-loop-logging +.. branch: no-release-gil .. branch: nobold-backtrace Work on improving UnionError messages and stack trace displays. diff --git a/pypy/interpreter/baseobjspace.py b/pypy/interpreter/baseobjspace.py --- a/pypy/interpreter/baseobjspace.py +++ b/pypy/interpreter/baseobjspace.py @@ -77,12 +77,12 @@ raise NotImplementedError("only for interp-level user subclasses " "from typedef.py") - def getname(self, space, default='?'): + def getname(self, space): try: return space.str_w(space.getattr(self, space.wrap('__name__'))) except OperationError, e: if e.match(space, space.w_TypeError) or e.match(space, space.w_AttributeError): - return default + return '?' raise def getaddrstring(self, space): diff --git a/pypy/interpreter/function.py b/pypy/interpreter/function.py --- a/pypy/interpreter/function.py +++ b/pypy/interpreter/function.py @@ -482,17 +482,16 @@ space.abstract_isinstance_w(w_firstarg, self.w_class)): pass # ok else: - clsdescr = self.w_class.getname(space, "") - if clsdescr: + clsdescr = self.w_class.getname(space) + if clsdescr and clsdescr != '?': clsdescr += " instance" else: clsdescr = "instance" if w_firstarg is None: instdescr = "nothing" else: - instname = space.abstract_getclass(w_firstarg).getname(space, - "") - if instname: + instname = space.abstract_getclass(w_firstarg).getname(space) + if instname and instname != '?': instdescr = instname + " instance" else: instdescr = "instance" diff --git a/pypy/interpreter/test/test_argument.py b/pypy/interpreter/test/test_argument.py --- a/pypy/interpreter/test/test_argument.py +++ b/pypy/interpreter/test/test_argument.py @@ -128,7 +128,7 @@ def type(self, obj): class Type: - def getname(self, space, default='?'): + def getname(self, space): return type(obj).__name__ return Type() diff --git a/pypy/module/__pypy__/interp_time.py b/pypy/module/__pypy__/interp_time.py --- a/pypy/module/__pypy__/interp_time.py +++ b/pypy/module/__pypy__/interp_time.py @@ -48,11 +48,11 @@ c_clock_gettime = rffi.llexternal("clock_gettime", [lltype.Signed, lltype.Ptr(TIMESPEC)], rffi.INT, - compilation_info=CConfig._compilation_info_, threadsafe=False + compilation_info=CConfig._compilation_info_, releasegil=False ) c_clock_getres = rffi.llexternal("clock_getres", [lltype.Signed, lltype.Ptr(TIMESPEC)], rffi.INT, - compilation_info=CConfig._compilation_info_, threadsafe=False + compilation_info=CConfig._compilation_info_, releasegil=False ) @unwrap_spec(clk_id="c_int") diff --git a/pypy/module/_cffi_backend/ccallback.py b/pypy/module/_cffi_backend/ccallback.py --- a/pypy/module/_cffi_backend/ccallback.py +++ b/pypy/module/_cffi_backend/ccallback.py @@ -54,6 +54,13 @@ if rffi.cast(lltype.Signed, res) != clibffi.FFI_OK: raise OperationError(space.w_SystemError, space.wrap("libffi failed to build this callback")) + # + # We must setup the GIL here, in case the callback is invoked in + # some other non-Pythonic thread. This is the same as cffi on + # CPython. + if space.config.translation.thread: + from pypy.module.thread.os_thread import setup_threads + setup_threads(space) def get_closure(self): return rffi.cast(clibffi.FFI_CLOSUREP, self._cdata) 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 @@ -26,6 +26,9 @@ def try_ldflags(): yield ExternalCompilationInfo(libraries=['curses']) yield ExternalCompilationInfo(libraries=['curses', 'tinfo']) + yield ExternalCompilationInfo(libraries=['ncurses']) + yield ExternalCompilationInfo(libraries=['ncurses'], + library_dirs=['/usr/lib64']) def try_tools(): try: 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 @@ -28,7 +28,7 @@ 'CreateSemaphoreA', [rffi.VOIDP, rffi.LONG, rffi.LONG, rwin32.LPCSTR], rwin32.HANDLE) _CloseHandle = rwin32.winexternal('CloseHandle', [rwin32.HANDLE], - rwin32.BOOL, threadsafe=False) + rwin32.BOOL, releasegil=False) _ReleaseSemaphore = rwin32.winexternal( 'ReleaseSemaphore', [rwin32.HANDLE, rffi.LONG, rffi.LONGP], rwin32.BOOL) @@ -82,8 +82,8 @@ _sem_open = external('sem_open', [rffi.CCHARP, rffi.INT, rffi.INT, rffi.UINT], SEM_T) - # tread sem_close as not threadsafe for now to be able to use the __del__ - _sem_close = external('sem_close', [SEM_T], rffi.INT, threadsafe=False) + # sem_close is releasegil=False to be able to use it in the __del__ + _sem_close = external('sem_close', [SEM_T], rffi.INT, releasegil=False) _sem_unlink = external('sem_unlink', [rffi.CCHARP], rffi.INT) _sem_wait = external('sem_wait', [SEM_T], rffi.INT) _sem_trywait = external('sem_trywait', [SEM_T], rffi.INT) 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 @@ -175,8 +175,8 @@ state = '; dead' else: typename = space.type(w_obj).getname(space) - objname = w_obj.getname(space, '') - if objname: + objname = w_obj.getname(space) + if objname and objname != '?': state = "; to '%s' (%s)" % (typename, objname) else: state = "; to '%s'" % (typename,) 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 @@ -144,12 +144,12 @@ BZ2_bzCompressInit = external('BZ2_bzCompressInit', [bz_stream, rffi.INT, rffi.INT, rffi.INT], rffi.INT) BZ2_bzCompressEnd = external('BZ2_bzCompressEnd', [bz_stream], rffi.INT, - threadsafe=False) + releasegil=False) BZ2_bzCompress = external('BZ2_bzCompress', [bz_stream, rffi.INT], rffi.INT) BZ2_bzDecompressInit = external('BZ2_bzDecompressInit', [bz_stream, rffi.INT, rffi.INT], rffi.INT) BZ2_bzDecompressEnd = external('BZ2_bzDecompressEnd', [bz_stream], rffi.INT, - threadsafe=False) + releasegil=False) BZ2_bzDecompress = external('BZ2_bzDecompress', [bz_stream], rffi.INT) def _catch_bz2_error(space, bzerror): diff --git a/pypy/module/cppyy/capi/builtin_capi.py b/pypy/module/cppyy/capi/builtin_capi.py --- a/pypy/module/cppyy/capi/builtin_capi.py +++ b/pypy/module/cppyy/capi/builtin_capi.py @@ -27,7 +27,7 @@ _c_num_scopes = rffi.llexternal( "cppyy_num_scopes", [C_SCOPE], rffi.INT, - threadsafe=ts_reflect, + releasegil=ts_reflect, compilation_info=backend.eci) def c_num_scopes(space, cppscope): return _c_num_scopes(cppscope.handle) @@ -41,28 +41,28 @@ _c_resolve_name = rffi.llexternal( "cppyy_resolve_name", [rffi.CCHARP], rffi.CCHARP, - threadsafe=ts_reflect, + releasegil=ts_reflect, compilation_info=backend.eci) def c_resolve_name(space, name): return charp2str_free(space, _c_resolve_name(name)) _c_get_scope_opaque = rffi.llexternal( "cppyy_get_scope", [rffi.CCHARP], C_SCOPE, - threadsafe=ts_reflect, + releasegil=ts_reflect, compilation_info=backend.eci) def c_get_scope_opaque(space, name): return _c_get_scope_opaque(name) _c_get_template = rffi.llexternal( "cppyy_get_template", [rffi.CCHARP], C_TYPE, - threadsafe=ts_reflect, + releasegil=ts_reflect, compilation_info=backend.eci) def c_get_template(space, name): return _c_get_template(name) _c_actual_class = rffi.llexternal( "cppyy_actual_class", [C_TYPE, C_OBJECT], C_TYPE, - threadsafe=ts_reflect, + releasegil=ts_reflect, compilation_info=backend.eci) def c_actual_class(space, cppclass, cppobj): return _c_actual_class(cppclass.handle, cppobj) @@ -71,21 +71,21 @@ _c_allocate = rffi.llexternal( "cppyy_allocate", [C_TYPE], C_OBJECT, - threadsafe=ts_memory, + releasegil=ts_memory, compilation_info=backend.eci) def c_allocate(space, cppclass): return _c_allocate(cppclass.handle) _c_deallocate = rffi.llexternal( "cppyy_deallocate", [C_TYPE, C_OBJECT], lltype.Void, - threadsafe=ts_memory, + releasegil=ts_memory, compilation_info=backend.eci) def c_deallocate(space, cppclass, cppobject): _c_deallocate(cppclass.handle, cppobject) _c_destruct = rffi.llexternal( "cppyy_destruct", [C_TYPE, C_OBJECT], lltype.Void, - threadsafe=ts_call, + releasegil=ts_call, compilation_info=backend.eci) def c_destruct(space, cppclass, cppobject): _c_destruct(cppclass.handle, cppobject) @@ -94,63 +94,63 @@ _c_call_v = rffi.llexternal( "cppyy_call_v", [C_METHOD, C_OBJECT, rffi.INT, rffi.VOIDP], lltype.Void, - threadsafe=ts_call, + releasegil=ts_call, compilation_info=backend.eci) def c_call_v(space, cppmethod, cppobject, nargs, args): _c_call_v(cppmethod, cppobject, nargs, args) _c_call_b = rffi.llexternal( "cppyy_call_b", [C_METHOD, C_OBJECT, rffi.INT, rffi.VOIDP], rffi.UCHAR, - threadsafe=ts_call, + releasegil=ts_call, compilation_info=backend.eci) def c_call_b(space, cppmethod, cppobject, nargs, args): return _c_call_b(cppmethod, cppobject, nargs, args) _c_call_c = rffi.llexternal( "cppyy_call_c", [C_METHOD, C_OBJECT, rffi.INT, rffi.VOIDP], rffi.CHAR, - threadsafe=ts_call, + releasegil=ts_call, compilation_info=backend.eci) def c_call_c(space, cppmethod, cppobject, nargs, args): return _c_call_c(cppmethod, cppobject, nargs, args) _c_call_h = rffi.llexternal( "cppyy_call_h", [C_METHOD, C_OBJECT, rffi.INT, rffi.VOIDP], rffi.SHORT, - threadsafe=ts_call, + releasegil=ts_call, compilation_info=backend.eci) def c_call_h(space, cppmethod, cppobject, nargs, args): return _c_call_h(cppmethod, cppobject, nargs, args) _c_call_i = rffi.llexternal( "cppyy_call_i", [C_METHOD, C_OBJECT, rffi.INT, rffi.VOIDP], rffi.INT, - threadsafe=ts_call, + releasegil=ts_call, compilation_info=backend.eci) def c_call_i(space, cppmethod, cppobject, nargs, args): return _c_call_i(cppmethod, cppobject, nargs, args) _c_call_l = rffi.llexternal( "cppyy_call_l", [C_METHOD, C_OBJECT, rffi.INT, rffi.VOIDP], rffi.LONG, - threadsafe=ts_call, + releasegil=ts_call, compilation_info=backend.eci) def c_call_l(space, cppmethod, cppobject, nargs, args): return _c_call_l(cppmethod, cppobject, nargs, args) _c_call_ll = rffi.llexternal( "cppyy_call_ll", [C_METHOD, C_OBJECT, rffi.INT, rffi.VOIDP], rffi.LONGLONG, - threadsafe=ts_call, + releasegil=ts_call, compilation_info=backend.eci) def c_call_ll(space, cppmethod, cppobject, nargs, args): return _c_call_ll(cppmethod, cppobject, nargs, args) _c_call_f = rffi.llexternal( "cppyy_call_f", [C_METHOD, C_OBJECT, rffi.INT, rffi.VOIDP], rffi.FLOAT, - threadsafe=ts_call, + releasegil=ts_call, compilation_info=backend.eci) def c_call_f(space, cppmethod, cppobject, nargs, args): return _c_call_f(cppmethod, cppobject, nargs, args) _c_call_d = rffi.llexternal( "cppyy_call_d", [C_METHOD, C_OBJECT, rffi.INT, rffi.VOIDP], rffi.DOUBLE, - threadsafe=ts_call, + releasegil=ts_call, compilation_info=backend.eci) def c_call_d(space, cppmethod, cppobject, nargs, args): return _c_call_d(cppmethod, cppobject, nargs, args) @@ -158,14 +158,14 @@ _c_call_r = rffi.llexternal( "cppyy_call_r", [C_METHOD, C_OBJECT, rffi.INT, rffi.VOIDP], rffi.VOIDP, - threadsafe=ts_call, + releasegil=ts_call, compilation_info=backend.eci) def c_call_r(space, cppmethod, cppobject, nargs, args): return _c_call_r(cppmethod, cppobject, nargs, args) _c_call_s = rffi.llexternal( "cppyy_call_s", [C_METHOD, C_OBJECT, rffi.INT, rffi.VOIDP], rffi.CCHARP, - threadsafe=ts_call, + releasegil=ts_call, compilation_info=backend.eci) def c_call_s(space, cppmethod, cppobject, nargs, args): return _c_call_s(cppmethod, cppobject, nargs, args) @@ -173,14 +173,14 @@ _c_constructor = rffi.llexternal( "cppyy_constructor", [C_METHOD, C_TYPE, rffi.INT, rffi.VOIDP], C_OBJECT, - threadsafe=ts_call, + releasegil=ts_call, compilation_info=backend.eci) def c_constructor(space, cppmethod, cppobject, nargs, args): return _c_constructor(cppmethod, cppobject, nargs, args) _c_call_o = rffi.llexternal( "cppyy_call_o", [C_METHOD, C_OBJECT, rffi.INT, rffi.VOIDP, C_TYPE], rffi.LONG, - threadsafe=ts_call, + releasegil=ts_call, compilation_info=backend.eci) def c_call_o(space, method, cppobj, nargs, args, cppclass): return _c_call_o(method, cppobj, nargs, args, cppclass.handle) @@ -188,7 +188,7 @@ _c_get_methptr_getter = rffi.llexternal( "cppyy_get_methptr_getter", [C_SCOPE, C_INDEX], C_METHPTRGETTER_PTR, - threadsafe=ts_reflect, + releasegil=ts_reflect, compilation_info=backend.eci, elidable_function=True) def c_get_methptr_getter(space, cppscope, index): @@ -198,21 +198,21 @@ _c_allocate_function_args = rffi.llexternal( "cppyy_allocate_function_args", [rffi.SIZE_T], rffi.VOIDP, - threadsafe=ts_memory, + releasegil=ts_memory, compilation_info=backend.eci) def c_allocate_function_args(space, size): return _c_allocate_function_args(size) _c_deallocate_function_args = rffi.llexternal( "cppyy_deallocate_function_args", [rffi.VOIDP], lltype.Void, - threadsafe=ts_memory, + releasegil=ts_memory, compilation_info=backend.eci) def c_deallocate_function_args(space, args): _c_deallocate_function_args(args) _c_function_arg_sizeof = rffi.llexternal( "cppyy_function_arg_sizeof", [], rffi.SIZE_T, - threadsafe=ts_memory, + releasegil=ts_memory, compilation_info=backend.eci, elidable_function=True) def c_function_arg_sizeof(space): @@ -220,7 +220,7 @@ _c_function_arg_typeoffset = rffi.llexternal( "cppyy_function_arg_typeoffset", [], rffi.SIZE_T, - threadsafe=ts_memory, + releasegil=ts_memory, compilation_info=backend.eci, elidable_function=True) def c_function_arg_typeoffset(space): @@ -230,14 +230,14 @@ _c_is_namespace = rffi.llexternal( "cppyy_is_namespace", [C_SCOPE], rffi.INT, - threadsafe=ts_reflect, + releasegil=ts_reflect, compilation_info=backend.eci) def c_is_namespace(space, scope): return _c_is_namespace(scope) _c_is_enum = rffi.llexternal( "cppyy_is_enum", [rffi.CCHARP], rffi.INT, - threadsafe=ts_reflect, + releasegil=ts_reflect, compilation_info=backend.eci) def c_is_enum(space, name): return _c_is_enum(name) @@ -246,42 +246,42 @@ _c_final_name = rffi.llexternal( "cppyy_final_name", [C_TYPE], rffi.CCHARP, - threadsafe=ts_reflect, + releasegil=ts_reflect, compilation_info=backend.eci) def c_final_name(space, cpptype): return charp2str_free(space, _c_final_name(cpptype)) _c_scoped_final_name = rffi.llexternal( "cppyy_scoped_final_name", [C_TYPE], rffi.CCHARP, - threadsafe=ts_reflect, + releasegil=ts_reflect, compilation_info=backend.eci) def c_scoped_final_name(space, cpptype): return charp2str_free(space, _c_scoped_final_name(cpptype)) _c_has_complex_hierarchy = rffi.llexternal( "cppyy_has_complex_hierarchy", [C_TYPE], rffi.INT, - threadsafe=ts_reflect, + releasegil=ts_reflect, compilation_info=backend.eci) def c_has_complex_hierarchy(space, cpptype): return _c_has_complex_hierarchy(cpptype) _c_num_bases = rffi.llexternal( "cppyy_num_bases", [C_TYPE], rffi.INT, - threadsafe=ts_reflect, + releasegil=ts_reflect, compilation_info=backend.eci) def c_num_bases(space, cppclass): return _c_num_bases(cppclass.handle) _c_base_name = rffi.llexternal( "cppyy_base_name", [C_TYPE, rffi.INT], rffi.CCHARP, - threadsafe=ts_reflect, + releasegil=ts_reflect, compilation_info=backend.eci) def c_base_name(space, cppclass, base_index): return charp2str_free(space, _c_base_name(cppclass.handle, base_index)) _c_is_subtype = rffi.llexternal( "cppyy_is_subtype", [C_TYPE, C_TYPE], rffi.INT, - threadsafe=ts_reflect, + releasegil=ts_reflect, compilation_info=backend.eci, elidable_function=True) @jit.elidable_promote('2') @@ -293,7 +293,7 @@ _c_base_offset = rffi.llexternal( "cppyy_base_offset", [C_TYPE, C_TYPE, C_OBJECT, rffi.INT], rffi.SIZE_T, - threadsafe=ts_reflect, + releasegil=ts_reflect, compilation_info=backend.eci, elidable_function=True) @jit.elidable_promote('1,2,4') @@ -308,21 +308,21 @@ _c_num_methods = rffi.llexternal( "cppyy_num_methods", [C_SCOPE], rffi.INT, - threadsafe=ts_reflect, + releasegil=ts_reflect, compilation_info=backend.eci) def c_num_methods(space, cppscope): return _c_num_methods(cppscope.handle) _c_method_index_at = rffi.llexternal( "cppyy_method_index_at", [C_SCOPE, rffi.INT], C_INDEX, - threadsafe=ts_reflect, + releasegil=ts_reflect, compilation_info=backend.eci) def c_method_index_at(space, cppscope, imethod): return _c_method_index_at(cppscope.handle, imethod) _c_method_indices_from_name = rffi.llexternal( "cppyy_method_indices_from_name", [C_SCOPE, rffi.CCHARP], C_INDEX_ARRAY, - threadsafe=ts_reflect, + releasegil=ts_reflect, compilation_info=backend.eci) def c_method_indices_from_name(space, cppscope, name): indices = _c_method_indices_from_name(cppscope.handle, name) @@ -341,49 +341,49 @@ _c_method_name = rffi.llexternal( "cppyy_method_name", [C_SCOPE, C_INDEX], rffi.CCHARP, - threadsafe=ts_reflect, + releasegil=ts_reflect, compilation_info=backend.eci) def c_method_name(space, cppscope, index): return charp2str_free(space, _c_method_name(cppscope.handle, index)) _c_method_result_type = rffi.llexternal( "cppyy_method_result_type", [C_SCOPE, C_INDEX], rffi.CCHARP, - threadsafe=ts_reflect, + releasegil=ts_reflect, compilation_info=backend.eci) def c_method_result_type(space, cppscope, index): return charp2str_free(space, _c_method_result_type(cppscope.handle, index)) _c_method_num_args = rffi.llexternal( "cppyy_method_num_args", [C_SCOPE, C_INDEX], rffi.INT, - threadsafe=ts_reflect, + releasegil=ts_reflect, compilation_info=backend.eci) def c_method_num_args(space, cppscope, index): return _c_method_num_args(cppscope.handle, index) _c_method_req_args = rffi.llexternal( "cppyy_method_req_args", [C_SCOPE, C_INDEX], rffi.INT, - threadsafe=ts_reflect, + releasegil=ts_reflect, compilation_info=backend.eci) def c_method_req_args(space, cppscope, index): return _c_method_req_args(cppscope.handle, index) _c_method_arg_type = rffi.llexternal( "cppyy_method_arg_type", [C_SCOPE, C_INDEX, rffi.INT], rffi.CCHARP, - threadsafe=ts_reflect, + releasegil=ts_reflect, compilation_info=backend.eci) def c_method_arg_type(space, cppscope, index, arg_index): return charp2str_free(space, _c_method_arg_type(cppscope.handle, index, arg_index)) _c_method_arg_default = rffi.llexternal( "cppyy_method_arg_default", [C_SCOPE, C_INDEX, rffi.INT], rffi.CCHARP, - threadsafe=ts_reflect, + releasegil=ts_reflect, compilation_info=backend.eci) def c_method_arg_default(space, cppscope, index, arg_index): return charp2str_free(space, _c_method_arg_default(cppscope.handle, index, arg_index)) _c_method_signature = rffi.llexternal( "cppyy_method_signature", [C_SCOPE, C_INDEX], rffi.CCHARP, - threadsafe=ts_reflect, + releasegil=ts_reflect, compilation_info=backend.eci) def c_method_signature(space, cppscope, index): return charp2str_free(space, _c_method_signature(cppscope.handle, index)) @@ -391,19 +391,19 @@ _c_method_is_template = rffi.llexternal( "cppyy_method_is_template", [C_SCOPE, C_INDEX], rffi.INT, - threadsafe=ts_reflect, + releasegil=ts_reflect, compilation_info=backend.eci) def c_method_is_template(space, 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, + releasegil=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, + releasegil=ts_reflect, compilation_info=backend.eci) def c_template_args(space, cppscope, index): nargs = _c_method_num_template_args(cppscope.handle, index) @@ -415,14 +415,14 @@ _c_get_method = rffi.llexternal( "cppyy_get_method", [C_SCOPE, C_INDEX], C_METHOD, - threadsafe=ts_reflect, + releasegil=ts_reflect, compilation_info=backend.eci) def c_get_method(space, cppscope, index): return _c_get_method(cppscope.handle, index) _c_get_global_operator = rffi.llexternal( "cppyy_get_global_operator", [C_SCOPE, C_SCOPE, C_SCOPE, rffi.CCHARP], WLAVC_INDEX, - threadsafe=ts_reflect, + releasegil=ts_reflect, compilation_info=backend.eci) def c_get_global_operator(space, nss, lc, rc, op): if nss is not None: @@ -433,14 +433,14 @@ _c_is_constructor = rffi.llexternal( "cppyy_is_constructor", [C_TYPE, C_INDEX], rffi.INT, - threadsafe=ts_reflect, + releasegil=ts_reflect, compilation_info=backend.eci) def c_is_constructor(space, cppclass, index): return _c_is_constructor(cppclass.handle, index) _c_is_staticmethod = rffi.llexternal( "cppyy_is_staticmethod", [C_TYPE, C_INDEX], rffi.INT, - threadsafe=ts_reflect, + releasegil=ts_reflect, compilation_info=backend.eci) def c_is_staticmethod(space, cppclass, index): return _c_is_staticmethod(cppclass.handle, index) @@ -449,28 +449,28 @@ _c_num_datamembers = rffi.llexternal( "cppyy_num_datamembers", [C_SCOPE], rffi.INT, - threadsafe=ts_reflect, + releasegil=ts_reflect, compilation_info=backend.eci) def c_num_datamembers(space, cppscope): return _c_num_datamembers(cppscope.handle) _c_datamember_name = rffi.llexternal( "cppyy_datamember_name", [C_SCOPE, rffi.INT], rffi.CCHARP, - threadsafe=ts_reflect, + releasegil=ts_reflect, compilation_info=backend.eci) def c_datamember_name(space, cppscope, datamember_index): return charp2str_free(space, _c_datamember_name(cppscope.handle, datamember_index)) _c_datamember_type = rffi.llexternal( "cppyy_datamember_type", [C_SCOPE, rffi.INT], rffi.CCHARP, - threadsafe=ts_reflect, + releasegil=ts_reflect, compilation_info=backend.eci) def c_datamember_type(space, cppscope, datamember_index): return charp2str_free(space, _c_datamember_type(cppscope.handle, datamember_index)) _c_datamember_offset = rffi.llexternal( "cppyy_datamember_offset", [C_SCOPE, rffi.INT], rffi.SIZE_T, - threadsafe=ts_reflect, + releasegil=ts_reflect, compilation_info=backend.eci) def c_datamember_offset(space, cppscope, datamember_index): return _c_datamember_offset(cppscope.handle, datamember_index) @@ -478,7 +478,7 @@ _c_datamember_index = rffi.llexternal( "cppyy_datamember_index", [C_SCOPE, rffi.CCHARP], rffi.INT, - threadsafe=ts_reflect, + releasegil=ts_reflect, compilation_info=backend.eci) def c_datamember_index(space, cppscope, name): return _c_datamember_index(cppscope.handle, name) @@ -487,14 +487,14 @@ _c_is_publicdata = rffi.llexternal( "cppyy_is_publicdata", [C_SCOPE, rffi.INT], rffi.INT, - threadsafe=ts_reflect, + releasegil=ts_reflect, compilation_info=backend.eci) def c_is_publicdata(space, cppscope, datamember_index): return _c_is_publicdata(cppscope.handle, datamember_index) _c_is_staticdata = rffi.llexternal( "cppyy_is_staticdata", [C_SCOPE, rffi.INT], rffi.INT, - threadsafe=ts_reflect, + releasegil=ts_reflect, compilation_info=backend.eci) def c_is_staticdata(space, cppscope, datamember_index): return _c_is_staticdata(cppscope.handle, datamember_index) @@ -503,21 +503,21 @@ _c_strtoll = rffi.llexternal( "cppyy_strtoll", [rffi.CCHARP], rffi.LONGLONG, - threadsafe=ts_helper, + releasegil=ts_helper, compilation_info=backend.eci) def c_strtoll(space, svalue): return _c_strtoll(svalue) _c_strtoull = rffi.llexternal( "cppyy_strtoull", [rffi.CCHARP], rffi.ULONGLONG, - threadsafe=ts_helper, + releasegil=ts_helper, compilation_info=backend.eci) def c_strtoull(space, svalue): return _c_strtoull(svalue) c_free = rffi.llexternal( "cppyy_free", [rffi.VOIDP], lltype.Void, - threadsafe=ts_memory, + releasegil=ts_memory, compilation_info=backend.eci) def charp2str_free(space, charp): @@ -529,7 +529,7 @@ _c_charp2stdstring = rffi.llexternal( "cppyy_charp2stdstring", [rffi.CCHARP], C_OBJECT, - threadsafe=ts_helper, + releasegil=ts_helper, compilation_info=backend.eci) def c_charp2stdstring(space, svalue): charp = rffi.str2charp(svalue) @@ -539,7 +539,7 @@ _c_stdstring2stdstring = rffi.llexternal( "cppyy_stdstring2stdstring", [C_OBJECT], C_OBJECT, - threadsafe=ts_helper, + releasegil=ts_helper, compilation_info=backend.eci) def c_stdstring2stdstring(space, cppobject): return _c_stdstring2stdstring(cppobject) 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 @@ -62,7 +62,7 @@ _c_load_dictionary = rffi.llexternal( "cppyy_load_dictionary", [rffi.CCHARP], rdynload.DLLHANDLE, - threadsafe=False, + releasegil=False, compilation_info=eci) def c_load_dictionary(name): @@ -76,7 +76,7 @@ _c_charp2TString = rffi.llexternal( "cppyy_charp2TString", [rffi.CCHARP], C_OBJECT, - threadsafe=ts_helper, + releasegil=ts_helper, compilation_info=eci) def c_charp2TString(space, svalue): charp = rffi.str2charp(svalue) @@ -86,7 +86,7 @@ _c_TString2TString = rffi.llexternal( "cppyy_TString2TString", [C_OBJECT], C_OBJECT, - threadsafe=ts_helper, + releasegil=ts_helper, compilation_info=eci) def c_TString2TString(space, cppobject): return _c_TString2TString(cppobject) @@ -105,7 +105,7 @@ _tfn_install = rffi.llexternal( "cppyy_tfn_install", [rffi.CCHARP, rffi.INT], rffi.LONG, - threadsafe=False, + releasegil=False, compilation_info=eci) @unwrap_spec(args_w='args_w') @@ -152,7 +152,7 @@ _ttree_Branch = rffi.llexternal( "cppyy_ttree_Branch", [rffi.VOIDP, rffi.CCHARP, rffi.CCHARP, rffi.VOIDP, rffi.INT, rffi.INT], rffi.LONG, - threadsafe=False, + releasegil=False, compilation_info=eci) @unwrap_spec(args_w='args_w') @@ -226,7 +226,7 @@ c_ttree_GetEntry = rffi.llexternal( "cppyy_ttree_GetEntry", [rffi.VOIDP, rffi.LONGLONG], rffi.LONGLONG, - threadsafe=False, + releasegil=False, compilation_info=eci) @unwrap_spec(args_w='args_w') diff --git a/pypy/module/crypt/interp_crypt.py b/pypy/module/crypt/interp_crypt.py --- a/pypy/module/crypt/interp_crypt.py +++ b/pypy/module/crypt/interp_crypt.py @@ -8,7 +8,7 @@ else: eci = ExternalCompilationInfo(libraries=['crypt']) c_crypt = rffi.llexternal('crypt', [rffi.CCHARP, rffi.CCHARP], rffi.CCHARP, - compilation_info=eci, threadsafe=False) + compilation_info=eci, releasegil=False) @unwrap_spec(word=str, salt=str) def crypt(space, word, salt): 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 @@ -776,7 +776,13 @@ def test_unicode_boxes(self): from numpypy import unicode_ - assert isinstance(unicode_(3), unicode) + try: + u = unicode_(3) + except NotImplementedError, e: + if e.message.find('not supported yet') >= 0: + skip('unicode box not implemented') + else: + assert isinstance(u, unicode) def test_character_dtype(self): from numpypy import array, character 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 @@ -356,7 +356,7 @@ XML_ParserCreateNS = expat_external( 'XML_ParserCreateNS', [rffi.CCHARP, rffi.CHAR], XML_Parser) XML_ParserFree = expat_external( - 'XML_ParserFree', [XML_Parser], lltype.Void, threadsafe=False) + 'XML_ParserFree', [XML_Parser], lltype.Void, releasegil=False) XML_SetUserData = expat_external( 'XML_SetUserData', [XML_Parser, rffi.VOIDP], lltype.Void) def XML_GetUserData(parser): 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 @@ -109,7 +109,8 @@ 'posix', '_socket', '_sre', '_lsprof', '_weakref', '__pypy__', 'cStringIO', '_collections', 'struct', 'mmap', 'marshal', '_codecs', 'rctime', 'cppyy', - '_cffi_backend', 'pyexpat', '_continuation', '_io']: + '_cffi_backend', 'pyexpat', '_continuation', '_io', + 'thread']: if modname == 'pypyjit' and 'interp_resop' in rest: return False return True diff --git a/pypy/module/pypyjit/test/test_policy.py b/pypy/module/pypyjit/test/test_policy.py --- a/pypy/module/pypyjit/test/test_policy.py +++ b/pypy/module/pypyjit/test/test_policy.py @@ -45,6 +45,10 @@ from pypy.module._io.interp_bytesio import W_BytesIO assert pypypolicy.look_inside_function(W_BytesIO.seek_w.im_func) +def test_thread(): + from pypy.module.thread.os_lock import Lock + assert pypypolicy.look_inside_function(Lock.descr_lock_acquire.im_func) + def test_pypy_module(): from pypy.module._collections.interp_deque import W_Deque from pypy.module._random.interp_random import W_Random 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 @@ -48,3 +48,47 @@ i58 = arraylen_gc(p43, descr=...) jump(..., descr=...) """) + + def test_lock_acquire_release(self): + def main(n): + import threading + lock = threading.Lock() + while n > 0: + with lock: + n -= 1 + log = self.run(main, [500]) + assert log.result == main(500) + loop, = log.loops_by_filename(self.filepath) + assert loop.match(""" + i58 = int_gt(i43, 0) + guard_true(i58, descr=) + p59 = getfield_gc(p15, descr=) + i60 = getfield_gc(p59, descr=) + p61 = force_token() + setfield_gc(p0, p61, descr=) + i62 = call_release_gil(4312440032, i60, 1, descr=) + guard_not_forced(descr=) + guard_no_exception(descr=) + i63 = int_is_true(i62) + guard_true(i63, descr=) + i64 = int_sub(i43, 1) + guard_not_invalidated(descr=) + p66 = getfield_gc(p15, descr=) + i67 = getfield_gc(p66, descr=) + p68 = force_token() + setfield_gc(p0, p68, descr=) + i69 = call_release_gil(4312440032, i67, 0, descr=) + guard_not_forced(descr=) + guard_no_exception(descr=) + i70 = int_is_true(i69) + guard_false(i70, descr=) + i71 = getfield_gc(p66, descr=) + p72 = force_token() + setfield_gc(p0, p72, descr=) + call_release_gil(4312441056, i71, descr=) + guard_not_forced(descr=) + guard_no_exception(descr=) + guard_not_invalidated(descr=) + --TICK-- + jump(..., descr=TargetToken(4361239720)) + """) 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 @@ -151,7 +151,7 @@ return rffi.llexternal(name, args, result, compilation_info=eci, calling_conv=calling_conv, - threadsafe=False) + releasegil=False) if _POSIX: cConfig.timeval.__name__ = "_timeval" diff --git a/pypy/module/test_lib_pypy/test_resource.py b/pypy/module/test_lib_pypy/test_resource.py --- a/pypy/module/test_lib_pypy/test_resource.py +++ b/pypy/module/test_lib_pypy/test_resource.py @@ -3,6 +3,9 @@ from lib_pypy.ctypes_config_cache import rebuild from pypy.module.test_lib_pypy.support import import_lib_pypy +import os +if os.name != 'posix': + skip('resource.h only available on unix') class AppTestResource: diff --git a/pypy/module/thread/test/test_thread.py b/pypy/module/thread/test/test_thread.py --- a/pypy/module/thread/test/test_thread.py +++ b/pypy/module/thread/test/test_thread.py @@ -187,9 +187,12 @@ skip("this OS supports too many threads to check (> 1000)") lock = thread.allocate_lock() lock.acquire() + count = [0] def f(): + count[0] += 1 lock.acquire() lock.release() + count[0] -= 1 try: try: for i in range(1000): @@ -197,11 +200,15 @@ finally: lock.release() # wait a bit to allow most threads to finish now - self.busywait(2.0) + while count[0] > 10: + print count[0] # <- releases the GIL + print "ok." except (thread.error, MemoryError): pass else: raise Exception("could unexpectedly start 1000 threads") + # safety: check that we can start a new thread here + thread.start_new_thread(lambda: None, ()) def test_stack_size(self): import thread diff --git a/pypy/objspace/descroperation.py b/pypy/objspace/descroperation.py --- a/pypy/objspace/descroperation.py +++ b/pypy/objspace/descroperation.py @@ -597,8 +597,8 @@ if num1 != num2: lt = num1 # if obj1 is a number, it is Lower Than obj2 else: - name1 = w_typ1.getname(space, "") - name2 = w_typ2.getname(space, "") + name1 = w_typ1.getname(space) + name2 = w_typ2.getname(space) if name1 != name2: lt = name1 < name2 else: 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 @@ -494,6 +494,12 @@ else: return w_self.name + def getname(w_self, space): + name = w_self.name + if name is None: + name = '?' + return name + def add_subclass(w_self, w_subclass): space = w_self.space if not space.config.translation.rweakref: 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 @@ -29,6 +29,7 @@ from rpython.rtyper.annlowlevel import llhelper, cast_instance_to_gcref from rpython.rtyper.lltypesystem import lltype, rffi from rpython.jit.backend.arm import callbuilder +from rpython.rtyper.lltypesystem.lloperation import llop class AssemblerARM(ResOpAssembler): @@ -1488,7 +1489,9 @@ def not_implemented(msg): - os.write(2, '[ARM/asm] %s\n' % msg) + msg = '[ARM/asm] %s\n' % msg + if we_are_translated(): + llop.debug_print(lltype.Void, msg) raise NotImplementedError(msg) 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 @@ -56,13 +56,13 @@ def finish_once(self): self.assembler.finish_once() - def compile_loop(self, logger, inputargs, operations, looptoken, - log=True, name=''): + def compile_loop(self, inputargs, operations, looptoken, + log=True, name='', logger=None): return self.assembler.assemble_loop(logger, name, inputargs, operations, looptoken, log=log) - def compile_bridge(self, logger, faildescr, inputargs, operations, - original_loop_token, log=True): + def compile_bridge(self, faildescr, inputargs, operations, + original_loop_token, log=True, logger=None): clt = original_loop_token.compiled_loop_token clt.compiling_a_bridge() return self.assembler.assemble_bridge(logger, faildescr, inputargs, 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 @@ -40,7 +40,7 @@ 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(None, inputargs, operations, looptoken) + cpu.compile_loop(inputargs, operations, looptoken) args = [-12 , -26 , -19 , 7 , -5 , -24 , -37 , 62 , 9 , 12] deadframe = cpu.execute_token(looptoken, *args) assert cpu.get_int_value(deadframe, 0) == 0 @@ -92,7 +92,7 @@ operations[9].setfailargs([v15, v7, v10, v18, v4, v17, v1]) operations[-1].setfailargs([v7, v1, v2]) looptoken = JitCellToken() - cpu.compile_loop(None, inputargs, operations, looptoken) + cpu.compile_loop(inputargs, operations, looptoken) args = [16 , 5 , 5 , 16 , 46 , 6 , 63 , 39 , 78 , 0] deadframe = cpu.execute_token(looptoken, *args) assert cpu.get_int_value(deadframe, 0) == 105 @@ -136,7 +136,7 @@ operations[-1].setfailargs([v5, v2, v1, v10, v3, v8, v4, v6]) looptoken = JitCellToken() - cpu.compile_loop(None, inputargs, operations, looptoken) + cpu.compile_loop(inputargs, operations, looptoken) args = [-5 , 24 , 46 , -15 , 13 , -8 , 0 , -6 , 6 , 6] deadframe = cpu.execute_token(looptoken, *args) assert cpu.get_latest_descr(deadframe).identifier == 2 @@ -179,7 +179,7 @@ operations[5].setfailargs([]) operations[-1].setfailargs([v8, v2, v6, v5, v7, v1, v10]) looptoken = JitCellToken() - cpu.compile_loop(None, inputargs, operations, looptoken) + cpu.compile_loop(inputargs, operations, looptoken) args = [19 , -3 , -58 , -7 , 12 , 22 , -54 , -29 , -19 , -64] deadframe = cpu.execute_token(looptoken, *args) assert cpu.get_int_value(deadframe, 0) == -29 @@ -223,7 +223,7 @@ looptoken = JitCellToken() operations[5].setfailargs([]) operations[-1].setfailargs([v1, v4, v10, v8, v7, v3]) - cpu.compile_loop(None, inputargs, operations, looptoken) + cpu.compile_loop(inputargs, operations, looptoken) args = [1073741824 , 95 , -16 , 5 , 92 , 12 , 32 , 17 , 37 , -63] deadframe = cpu.execute_token(looptoken, *args) assert cpu.get_int_value(deadframe, 0) == 1073741824 @@ -280,7 +280,7 @@ 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(None, inputargs, operations, looptoken) + cpu.compile_loop(inputargs, operations, looptoken) deadframe = cpu.execute_token(looptoken, *args) assert cpu.get_latest_descr(deadframe).identifier == 3 assert cpu.get_int_value(deadframe, 0) == 12 @@ -328,7 +328,7 @@ operations[8].setfailargs([v5, v9]) operations[-1].setfailargs([v4, v10, v6, v5, v9, v7]) looptoken = JitCellToken() - cpu.compile_loop(None, inputargs, operations, looptoken) + cpu.compile_loop(inputargs, operations, looptoken) args = [-8 , 0 , 62 , 35 , 16 , 9 , 30 , 581610154 , -1 , 738197503] deadframe = cpu.execute_token(looptoken, *args) assert cpu.get_latest_descr(deadframe).identifier == 2 @@ -378,7 +378,7 @@ operations[-2].setfailargs([v9, v4, v10, v11, v14]) operations[-1].setfailargs([v10, v8, v1, v6, v4]) looptoken = JitCellToken() - cpu.compile_loop(None, inputargs, operations, looptoken) + cpu.compile_loop(inputargs, operations, looptoken) args = [-39 , -18 , 1588243114 , -9 , -4 , 1252698794 , 0 , 715827882 , -15 , 536870912] deadframe = cpu.execute_token(looptoken, *args) assert cpu.get_latest_descr(deadframe).identifier == 1 @@ -433,7 +433,7 @@ operations[9].setfailargs([v5, v7, v12, v14, v2, v13, v8]) operations[-1].setfailargs([v1, v2, v9]) looptoken = JitCellToken() - cpu.compile_loop(None, inputargs, operations, looptoken) + cpu.compile_loop(inputargs, operations, looptoken) args = [0 , -2 , 24 , 1 , -4 , 13 , -95 , 33 , 2 , -44] deadframe = cpu.execute_token(looptoken, *args) assert cpu.get_latest_descr(deadframe).identifier == 3 @@ -475,7 +475,7 @@ 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(None, inputargs, operations, looptoken) + cpu.compile_loop(inputargs, operations, looptoken) args = [3 , -5 , 1431655765 , 47 , 12 , 1789569706 , 15 , 939524096 , 16 , -43] deadframe = cpu.execute_token(looptoken, *args) assert cpu.get_latest_descr(deadframe).identifier == 1 @@ -524,7 +524,7 @@ operations[-1].setfailargs([v2, v3, v5, v7, v10, v8, v9]) operations[4].setfailargs([v14]) looptoken = JitCellToken() - cpu.compile_loop(None, inputargs, operations, looptoken) + cpu.compile_loop(inputargs, operations, looptoken) args = [14 , -20 , 18 , -2058005163 , 6 , 1 , -16 , 11 , 0 , 19] deadframe = cpu.execute_token(looptoken, *args) assert cpu.get_latest_descr(deadframe).identifier == 1 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 @@ -24,7 +24,7 @@ cpu = CPU(None, None) cpu.setup_once() looptoken = JitCellToken() - cpu.compile_loop(None, inputargs, operations, looptoken) + cpu.compile_loop(inputargs, operations, looptoken) deadframe = cpu.execute_token(looptoken, 9) assert cpu.get_int_value(deadframe, 0) == (9 >> 3) assert cpu.get_int_value(deadframe, 1) == (~18) @@ -48,7 +48,7 @@ cpu = CPU(None, None) cpu.setup_once() looptoken = JitCellToken() - cpu.compile_loop(None, inputargs, operations, looptoken) + cpu.compile_loop(inputargs, operations, looptoken) deadframe = cpu.execute_token(looptoken, -10) assert cpu.get_int_value(deadframe, 0) == 0 assert cpu.get_int_value(deadframe, 1) == -1000 @@ -145,7 +145,7 @@ cpu = CPU(None, None) cpu.setup_once() looptoken = JitCellToken() - cpu.compile_loop(None, inputargs, operations, looptoken) + cpu.compile_loop(inputargs, operations, looptoken) args = [-13 , 10 , 10 , 8 , -8 , -16 , -18 , 46 , -12 , 26] deadframe = cpu.execute_token(looptoken, *args) assert cpu.get_int_value(deadframe, 0) == 0 @@ -252,7 +252,7 @@ cpu = CPU(None, None) cpu.setup_once() looptoken = JitCellToken() - cpu.compile_loop(None, inputargs, operations, looptoken) + cpu.compile_loop(inputargs, operations, looptoken) args = [17 , -20 , -6 , 6 , 1 , 13 , 13 , 9 , 49 , 8] deadframe = cpu.execute_token(looptoken, *args) assert cpu.get_int_value(deadframe, 0) == 0 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 @@ -75,7 +75,7 @@ ResOperation(rop.FINISH, [inp[1]], None, descr=BasicFinalDescr(1)), ] operations[-2].setfailargs(out) - cpu.compile_loop(None, inp, operations, looptoken) + cpu.compile_loop(inp, operations, looptoken) args = [i for i in range(1, 15)] deadframe = self.cpu.execute_token(looptoken, *args) output = [self.cpu.get_int_value(deadframe, i - 1) for i in range(1, 15)] @@ -117,9 +117,9 @@ i1 = int_sub(i0, 1) finish(i1) ''') - self.cpu.compile_loop(None, loop2.inputargs, loop2.operations, lt2) - self.cpu.compile_loop(None, loop3.inputargs, loop3.operations, lt3) - self.cpu.compile_loop(None, loop1.inputargs, loop1.operations, lt1) + self.cpu.compile_loop(loop2.inputargs, loop2.operations, lt2) + self.cpu.compile_loop(loop3.inputargs, loop3.operations, lt3) + self.cpu.compile_loop(loop1.inputargs, loop1.operations, lt1) df = self.cpu.execute_token(lt1, 10) assert self.cpu.get_int_value(df, 0) == 7 @@ -214,7 +214,7 @@ ops = "".join(ops) loop = parse(ops) looptoken = JitCellToken() - self.cpu.compile_loop(None, loop.inputargs, loop.operations, looptoken) + self.cpu.compile_loop(loop.inputargs, loop.operations, looptoken) ARGS = [lltype.Signed] * numargs RES = lltype.Signed args = [i+1 for i in range(numargs)] @@ -246,7 +246,7 @@ try: self.cpu.assembler.set_debug(True) looptoken = JitCellToken() - self.cpu.compile_loop(None, ops.inputargs, ops.operations, looptoken) + self.cpu.compile_loop(ops.inputargs, ops.operations, looptoken) self.cpu.execute_token(looptoken, 0) # check debugging info struct = self.cpu.assembler.loop_run_counters[0] @@ -280,7 +280,7 @@ faildescr = BasicFailDescr(2) loop = parse(ops, self.cpu, namespace=locals()) looptoken = JitCellToken() - info = self.cpu.compile_loop(None, loop.inputargs, loop.operations, looptoken) + info = self.cpu.compile_loop(loop.inputargs, loop.operations, looptoken) ops2 = """ [i0, f1] i1 = same_as(i0) @@ -293,7 +293,7 @@ """ loop2 = parse(ops2, self.cpu, namespace=locals()) looptoken2 = JitCellToken() - info = self.cpu.compile_loop(None, loop2.inputargs, loop2.operations, looptoken2) + info = self.cpu.compile_loop(loop2.inputargs, loop2.operations, looptoken2) deadframe = self.cpu.execute_token(looptoken, -9, longlong.getfloatstorage(-13.5)) res = longlong.getrealfloat(self.cpu.get_float_value(deadframe, 0)) 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 @@ -183,8 +183,8 @@ self.stats = stats or MiniStats() self.vinfo_for_tests = kwds.get('vinfo_for_tests', None) - def compile_loop(self, logger, inputargs, operations, looptoken, log=True, - name=''): + def compile_loop(self, inputargs, operations, looptoken, log=True, + name='', logger=None): clt = model.CompiledLoopToken(self, looptoken.number) looptoken.compiled_loop_token = clt lltrace = LLTrace(inputargs, operations) @@ -192,8 +192,8 @@ clt._llgraph_alltraces = [lltrace] self._record_labels(lltrace) - def compile_bridge(self, logger, faildescr, inputargs, operations, - original_loop_token, log=True): + def compile_bridge(self, faildescr, inputargs, operations, + original_loop_token, log=True, logger=None): clt = original_loop_token.compiled_loop_token clt.compiling_a_bridge() lltrace = LLTrace(inputargs, operations) @@ -418,7 +418,6 @@ bh_setfield_raw = bh_setfield_gc bh_setfield_raw_i = bh_setfield_raw - bh_setfield_raw_r = bh_setfield_raw bh_setfield_raw_f = bh_setfield_raw def bh_arraylen_gc(self, a, descr): 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 @@ -64,8 +64,6 @@ return True def initialize(self): pass - def do_write_barrier(self, gcref_struct, gcref_newptr): - pass def can_use_nursery_malloc(self, size): return False def has_write_barrier_class(self): @@ -135,9 +133,7 @@ def malloc_jitframe(self, frame_info): """ Allocate a new frame, overwritten by tests """ - frame = jitframe.JITFRAME.allocate(frame_info) - llop.gc_writebarrier(lltype.Void, frame) - return frame + return jitframe.JITFRAME.allocate(frame_info) class JitFrameDescrs: def _freeze_(self): @@ -547,17 +543,6 @@ hdr = llmemory.cast_adr_to_ptr(hdr_addr, self.HDRPTR) hdr.tid = tid - def do_write_barrier(self, gcref_struct, gcref_newptr): - hdr_addr = llmemory.cast_ptr_to_adr(gcref_struct) - hdr_addr -= self.gcheaderbuilder.size_gc_header - hdr = llmemory.cast_adr_to_ptr(hdr_addr, self.HDRPTR) - if hdr.tid & self.GCClass.JIT_WB_IF_FLAG: - # get a pointer to the 'remember_young_pointer' function from - # the GC, and call it immediately - llop1 = self.llop1 - funcptr = llop1.get_write_barrier_failing_case(self.WB_FUNCPTR) - funcptr(llmemory.cast_ptr_to_adr(gcref_struct)) - def can_use_nursery_malloc(self, size): return size < self.max_size_of_young_obj 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 @@ -247,6 +247,7 @@ else: assert kind == history.REF self.set_ref_value(ll_frame, num, arg) + llop.gc_writebarrier(lltype.Void, ll_frame) ll_frame = func(ll_frame) finally: if not self.translate_support_code: @@ -368,68 +369,44 @@ @specialize.argtype(1) def read_int_at_mem(self, gcref, ofs, size, sign): - # --- start of GC unsafe code (no GC operation!) --- - items = rffi.ptradd(rffi.cast(rffi.CCHARP, gcref), ofs) for STYPE, UTYPE, itemsize in unroll_basic_sizes: if size == itemsize: if sign: - items = rffi.cast(rffi.CArrayPtr(STYPE), items) - val = items[0] + val = llop.raw_load(STYPE, gcref, ofs) val = rffi.cast(lltype.Signed, val) else: - items = rffi.cast(rffi.CArrayPtr(UTYPE), items) - val = items[0] + val = llop.raw_load(UTYPE, gcref, ofs) val = rffi.cast(lltype.Signed, val) - # --- end of GC unsafe code --- return val else: raise NotImplementedError("size = %d" % size) @specialize.argtype(1) - def write_int_at_mem(self, gcref, ofs, size, sign, newvalue): - # --- start of GC unsafe code (no GC operation!) --- - items = rffi.ptradd(rffi.cast(rffi.CCHARP, gcref), ofs) + def write_int_at_mem(self, gcref, ofs, size, newvalue): for TYPE, _, itemsize in unroll_basic_sizes: if size == itemsize: - items = rffi.cast(rffi.CArrayPtr(TYPE), items) - items[0] = rffi.cast(TYPE, newvalue) - # --- end of GC unsafe code --- + newvalue = rffi.cast(TYPE, newvalue) + llop.raw_store(lltype.Void, gcref, ofs, newvalue) return else: raise NotImplementedError("size = %d" % size) + @specialize.argtype(1) def read_ref_at_mem(self, gcref, ofs): - # --- start of GC unsafe code (no GC operation!) --- - items = rffi.ptradd(rffi.cast(rffi.CCHARP, gcref), ofs) - items = rffi.cast(rffi.CArrayPtr(lltype.Signed), items) - pval = self._cast_int_to_gcref(items[0]) - # --- end of GC unsafe code --- - return pval + return llop.raw_load(llmemory.GCREF, gcref, ofs) + # non- at specialized: must only be called with llmemory.GCREF def write_ref_at_mem(self, gcref, ofs, newvalue): - self.gc_ll_descr.do_write_barrier(gcref, newvalue) - # --- start of GC unsafe code (no GC operation!) --- - items = rffi.ptradd(rffi.cast(rffi.CCHARP, gcref), ofs) - items = rffi.cast(rffi.CArrayPtr(lltype.Signed), items) - items[0] = self.cast_gcref_to_int(newvalue) - # --- end of GC unsafe code --- + llop.raw_store(lltype.Void, gcref, ofs, newvalue) + # the write barrier is implied above @specialize.argtype(1) def read_float_at_mem(self, gcref, ofs): - # --- start of GC unsafe code (no GC operation!) --- - items = rffi.ptradd(rffi.cast(rffi.CCHARP, gcref), ofs) - items = rffi.cast(rffi.CArrayPtr(longlong.FLOATSTORAGE), items) - fval = items[0] - # --- end of GC unsafe code --- - return fval + return llop.raw_load(longlong.FLOATSTORAGE, gcref, ofs) @specialize.argtype(1) def write_float_at_mem(self, gcref, ofs, newvalue): - # --- start of GC unsafe code (no GC operation!) --- - items = rffi.ptradd(rffi.cast(rffi.CCHARP, gcref), ofs) - items = rffi.cast(rffi.CArrayPtr(longlong.FLOATSTORAGE), items) - items[0] = newvalue - # --- end of GC unsafe code --- + llop.raw_store(lltype.Void, gcref, ofs, newvalue) # ____________________________________________________________ @@ -439,7 +416,7 @@ """ descr = self.gc_ll_descr.getframedescrs(self).arraydescr ofs = self.unpack_arraydescr(descr) - self.write_int_at_mem(newframe, ofs + index, WORD, 1, value) + self.write_int_at_mem(newframe, ofs + index, WORD, value) def set_ref_value(self, newframe, index, value): descr = self.gc_ll_descr.getframedescrs(self).arraydescr @@ -467,7 +444,7 @@ def bh_arraylen_gc(self, array, arraydescr): assert isinstance(arraydescr, ArrayDescr) ofs = arraydescr.lendescr.offset - return rffi.cast(rffi.CArrayPtr(lltype.Signed), array)[ofs/WORD] + return self.read_int_at_mem(array, ofs, WORD, 1) @specialize.argtype(1) def bh_getarrayitem_gc_i(self, gcref, itemindex, arraydescr): @@ -488,8 +465,7 @@ @specialize.argtype(1) def bh_setarrayitem_gc_i(self, gcref, itemindex, newvalue, arraydescr): ofs, size, sign = self.unpack_arraydescr_size(arraydescr) - self.write_int_at_mem(gcref, ofs + itemindex * size, size, sign, - newvalue) + self.write_int_at_mem(gcref, ofs + itemindex * size, size, newvalue) def bh_setarrayitem_gc_r(self, gcref, itemindex, newvalue, arraydescr): ofs = self.unpack_arraydescr(arraydescr) @@ -509,97 +485,43 @@ def bh_getinteriorfield_gc_i(self, gcref, itemindex, descr): assert isinstance(descr, InteriorFieldDescr) - arraydescr = descr.arraydescr - ofs, size, _ = self.unpack_arraydescr_size(arraydescr) - ofs += descr.fielddescr.offset - fieldsize = descr.fielddescr.field_size - sign = descr.fielddescr.is_field_signed() - fullofs = itemindex * size + ofs - # --- start of GC unsafe code (no GC operation!) --- - items = rffi.ptradd(rffi.cast(rffi.CCHARP, gcref), fullofs) - for STYPE, UTYPE, itemsize in unroll_basic_sizes: - if fieldsize == itemsize: - if sign: - item = rffi.cast(rffi.CArrayPtr(STYPE), items) - val = item[0] - val = rffi.cast(lltype.Signed, val) - else: - item = rffi.cast(rffi.CArrayPtr(UTYPE), items) - val = item[0] - val = rffi.cast(lltype.Signed, val) - # --- end of GC unsafe code --- - return val - else: - raise NotImplementedError("size = %d" % fieldsize) + ofs, size, _ = self.unpack_arraydescr_size(descr.arraydescr) + fldofs, fldsize, sign = self.unpack_fielddescr_size(descr.fielddescr) + ofs += itemindex * size + fldofs + return self.read_int_at_mem(gcref, ofs, fldsize, sign) def bh_getinteriorfield_gc_r(self, gcref, itemindex, descr): assert isinstance(descr, InteriorFieldDescr) - arraydescr = descr.arraydescr - ofs, size, _ = self.unpack_arraydescr_size(arraydescr) + ofs, size, _ = self.unpack_arraydescr_size(descr.arraydescr) ofs += descr.fielddescr.offset - # --- start of GC unsafe code (no GC operation!) --- - items = rffi.ptradd(rffi.cast(rffi.CCHARP, gcref), ofs + - size * itemindex) - items = rffi.cast(rffi.CArrayPtr(lltype.Signed), items) - pval = self._cast_int_to_gcref(items[0]) - # --- end of GC unsafe code --- - return pval + fullofs = itemindex * size + ofs + return self.read_ref_at_mem(gcref, fullofs) def bh_getinteriorfield_gc_f(self, gcref, itemindex, descr): assert isinstance(descr, InteriorFieldDescr) - arraydescr = descr.arraydescr - ofs, size, _ = self.unpack_arraydescr_size(arraydescr) + ofs, size, _ = self.unpack_arraydescr_size(descr.arraydescr) ofs += descr.fielddescr.offset - # --- start of GC unsafe code (no GC operation!) --- - items = rffi.ptradd(rffi.cast(rffi.CCHARP, gcref), ofs + - size * itemindex) - items = rffi.cast(rffi.CArrayPtr(longlong.FLOATSTORAGE), items) - fval = items[0] - # --- end of GC unsafe code --- - return fval + fullofs = itemindex * size + ofs + return self.read_float_at_mem(gcref, fullofs) - def bh_setinteriorfield_gc_i(self, gcref, itemindex, value, descr): + def bh_setinteriorfield_gc_i(self, gcref, itemindex, newvalue, descr): assert isinstance(descr, InteriorFieldDescr) - arraydescr = descr.arraydescr - ofs, size, _ = self.unpack_arraydescr_size(arraydescr) - ofs += descr.fielddescr.offset - fieldsize = descr.fielddescr.field_size - ofs = itemindex * size + ofs - # --- start of GC unsafe code (no GC operation!) --- - items = rffi.ptradd(rffi.cast(rffi.CCHARP, gcref), ofs) - for TYPE, _, itemsize in unroll_basic_sizes: - if fieldsize == itemsize: - items = rffi.cast(rffi.CArrayPtr(TYPE), items) - items[0] = rffi.cast(TYPE, value) - # --- end of GC unsafe code --- - return - else: - raise NotImplementedError("size = %d" % fieldsize) + ofs, size, _ = self.unpack_arraydescr_size(descr.arraydescr) + fldofs, fldsize, _ = self.unpack_fielddescr_size(descr.fielddescr) + ofs += itemindex * size + fldofs + self.write_int_at_mem(gcref, ofs, fldsize, newvalue) def bh_setinteriorfield_gc_r(self, gcref, itemindex, newvalue, descr): assert isinstance(descr, InteriorFieldDescr) - arraydescr = descr.arraydescr - ofs, size, _ = self.unpack_arraydescr_size(arraydescr) - ofs += descr.fielddescr.offset - self.gc_ll_descr.do_write_barrier(gcref, newvalue) - # --- start of GC unsafe code (no GC operation!) --- - items = rffi.ptradd(rffi.cast(rffi.CCHARP, gcref), - ofs + size * itemindex) - items = rffi.cast(rffi.CArrayPtr(lltype.Signed), items) - items[0] = self.cast_gcref_to_int(newvalue) - # --- end of GC unsafe code --- + ofs, size, _ = self.unpack_arraydescr_size(descr.arraydescr) + ofs += itemindex * size + descr.fielddescr.offset + self.write_ref_at_mem(gcref, ofs, newvalue) def bh_setinteriorfield_gc_f(self, gcref, itemindex, newvalue, descr): assert isinstance(descr, InteriorFieldDescr) - arraydescr = descr.arraydescr - ofs, size, _ = self.unpack_arraydescr_size(arraydescr) - ofs += descr.fielddescr.offset - # --- start of GC unsafe code (no GC operation!) --- - items = rffi.ptradd(rffi.cast(rffi.CCHARP, gcref), - ofs + size * itemindex) - items = rffi.cast(rffi.CArrayPtr(longlong.FLOATSTORAGE), items) - items[0] = newvalue - # --- end of GC unsafe code --- + ofs, size, _ = self.unpack_arraydescr_size(descr.arraydescr) + ofs += itemindex * size + descr.fielddescr.offset + self.write_float_at_mem(gcref, ofs, newvalue) def bh_strlen(self, string): s = lltype.cast_opaque_ptr(lltype.Ptr(rstr.STR), string) @@ -618,106 +540,48 @@ return ord(u.chars[index]) @specialize.argtype(1) - def _base_do_getfield_i(self, struct, fielddescr): + def bh_getfield_gc_i(self, struct, fielddescr): ofs, size, sign = self.unpack_fielddescr_size(fielddescr) - # --- start of GC unsafe code (no GC operation!) --- - fieldptr = rffi.ptradd(rffi.cast(rffi.CCHARP, struct), ofs) - for STYPE, UTYPE, itemsize in unroll_basic_sizes: - if size == itemsize: - # Note that in the common case where size==sizeof(Signed), - # both cases of what follows are doing the same thing. - # But gcc is clever enough to figure this out :-) - if sign: - val = rffi.cast(rffi.CArrayPtr(STYPE), fieldptr)[0] - val = rffi.cast(lltype.Signed, val) - else: - val = rffi.cast(rffi.CArrayPtr(UTYPE), fieldptr)[0] - val = rffi.cast(lltype.Signed, val) - # --- end of GC unsafe code --- - return val - else: - raise NotImplementedError("size = %d" % size) + return self.read_int_at_mem(struct, ofs, size, sign) @specialize.argtype(1) - def _base_do_getfield_r(self, struct, fielddescr): + def bh_getfield_gc_r(self, struct, fielddescr): ofs = self.unpack_fielddescr(fielddescr) - # --- start of GC unsafe code (no GC operation!) --- - fieldptr = rffi.ptradd(rffi.cast(rffi.CCHARP, struct), ofs) - pval = rffi.cast(rffi.CArrayPtr(lltype.Signed), fieldptr)[0] - pval = self._cast_int_to_gcref(pval) - # --- end of GC unsafe code --- - return pval + return self.read_ref_at_mem(struct, ofs) @specialize.argtype(1) - def _base_do_getfield_f(self, struct, fielddescr): + def bh_getfield_gc_f(self, struct, fielddescr): ofs = self.unpack_fielddescr(fielddescr) - # --- start of GC unsafe code (no GC operation!) --- - fieldptr = rffi.ptradd(rffi.cast(rffi.CCHARP, struct), ofs) - fval = rffi.cast(rffi.CArrayPtr(longlong.FLOATSTORAGE), fieldptr)[0] - # --- end of GC unsafe code --- - return fval + return self.read_float_at_mem(struct, ofs) - bh_getfield_gc_i = _base_do_getfield_i - bh_getfield_gc_r = _base_do_getfield_r - bh_getfield_gc_f = _base_do_getfield_f - bh_getfield_raw_i = _base_do_getfield_i - bh_getfield_raw_r = _base_do_getfield_r - bh_getfield_raw_f = _base_do_getfield_f + bh_getfield_raw_i = bh_getfield_gc_i + bh_getfield_raw_r = bh_getfield_gc_r + bh_getfield_raw_f = bh_getfield_gc_f @specialize.argtype(1) - def _base_do_setfield_i(self, struct, newvalue, fielddescr): - ofs, size, sign = self.unpack_fielddescr_size(fielddescr) - # --- start of GC unsafe code (no GC operation!) --- - fieldptr = rffi.ptradd(rffi.cast(rffi.CCHARP, struct), ofs) - for TYPE, _, itemsize in unroll_basic_sizes: - if size == itemsize: - fieldptr = rffi.cast(rffi.CArrayPtr(TYPE), fieldptr) - fieldptr[0] = rffi.cast(TYPE, newvalue) - # --- end of GC unsafe code --- - return - else: - raise NotImplementedError("size = %d" % size) + def bh_setfield_gc_i(self, struct, newvalue, fielddescr): + ofs, size, _ = self.unpack_fielddescr_size(fielddescr) + self.write_int_at_mem(struct, ofs, size, newvalue) + + def bh_setfield_gc_r(self, struct, newvalue, fielddescr): + ofs = self.unpack_fielddescr(fielddescr) + self.write_ref_at_mem(struct, ofs, newvalue) @specialize.argtype(1) - def _base_do_setfield_r(self, struct, newvalue, fielddescr): + def bh_setfield_gc_f(self, struct, newvalue, fielddescr): ofs = self.unpack_fielddescr(fielddescr) - assert lltype.typeOf(struct) is not lltype.Signed, ( - "can't handle write barriers for setfield_raw") - self.gc_ll_descr.do_write_barrier(struct, newvalue) - # --- start of GC unsafe code (no GC operation!) --- - fieldptr = rffi.ptradd(rffi.cast(rffi.CCHARP, struct), ofs) - fieldptr = rffi.cast(rffi.CArrayPtr(lltype.Signed), fieldptr) - fieldptr[0] = self.cast_gcref_to_int(newvalue) - # --- end of GC unsafe code --- + self.write_float_at_mem(struct, ofs, newvalue) - @specialize.argtype(1) - def _base_do_setfield_f(self, struct, newvalue, fielddescr): - ofs = self.unpack_fielddescr(fielddescr) - # --- start of GC unsafe code (no GC operation!) --- - fieldptr = rffi.ptradd(rffi.cast(rffi.CCHARP, struct), ofs) - fieldptr = rffi.cast(rffi.CArrayPtr(longlong.FLOATSTORAGE), fieldptr) - fieldptr[0] = newvalue - # --- end of GC unsafe code --- - - bh_setfield_gc_i = _base_do_setfield_i - bh_setfield_gc_r = _base_do_setfield_r - bh_setfield_gc_f = _base_do_setfield_f - bh_setfield_raw_i = _base_do_setfield_i - bh_setfield_raw_r = _base_do_setfield_r - bh_setfield_raw_f = _base_do_setfield_f + bh_setfield_raw_i = bh_setfield_gc_i + bh_setfield_raw_f = bh_setfield_gc_f def bh_raw_store_i(self, addr, offset, newvalue, descr): - ofs, size, sign = self.unpack_arraydescr_size(descr) - items = addr + offset - for TYPE, _, itemsize in unroll_basic_sizes: - if size == itemsize: - items = rffi.cast(rffi.CArrayPtr(TYPE), items) - items[0] = rffi.cast(TYPE, newvalue) - break + ofs, size, _ = self.unpack_arraydescr_size(descr) + assert ofs == 0 # otherwise, 'descr' is not a raw length-less array + self.write_int_at_mem(addr, offset, size, newvalue) def bh_raw_store_f(self, addr, offset, newvalue, descr): - items = rffi.cast(rffi.CArrayPtr(longlong.FLOATSTORAGE), addr + offset) - items[0] = newvalue + self.write_float_at_mem(addr, offset, newvalue) def bh_raw_load_i(self, addr, offset, descr): ofs, size, sign = self.unpack_arraydescr_size(descr) @@ -725,8 +589,7 @@ return self.read_int_at_mem(addr, offset, size, sign) def bh_raw_load_f(self, addr, offset, descr): - items = rffi.cast(rffi.CArrayPtr(longlong.FLOATSTORAGE), addr + offset) - return items[0] + return self.read_float_at_mem(addr, offset) def bh_new(self, sizedescr): return self.gc_ll_descr.gc_malloc(sizedescr) @@ -734,8 +597,7 @@ def bh_new_with_vtable(self, vtable, sizedescr): res = self.gc_ll_descr.gc_malloc(sizedescr) if self.vtable_offset is not None: - as_array = rffi.cast(rffi.CArrayPtr(lltype.Signed), res) - as_array[self.vtable_offset/WORD] = vtable + self.write_int_at_mem(res, self.vtable_offset, WORD, vtable) return res def bh_new_raw_buffer(self, size): 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 @@ -2,6 +2,8 @@ from rpython.jit.metainterp.history import Const, Box, REF, JitCellToken from rpython.rlib.objectmodel import we_are_translated, specialize from rpython.jit.metainterp.resoperation import rop +from rpython.rtyper.lltypesystem import lltype +from rpython.rtyper.lltypesystem.lloperation import llop try: from collections import OrderedDict @@ -66,14 +68,32 @@ function(arg, node.val) node = node.next From noreply at buildbot.pypy.org Fri Sep 20 08:36:38 2013 From: noreply at buildbot.pypy.org (wlav) Date: Fri, 20 Sep 2013 08:36:38 +0200 (CEST) Subject: [pypy-commit] pypy reflex-support: store (app-level) pyfuncs in a cache and simply callback returns Message-ID: <20130920063638.166BF1C0209@cobra.cs.uni-duesseldorf.de> Author: Wim Lavrijsen Branch: reflex-support Changeset: r67019:e971012143a5 Date: 2013-09-17 14:10 -0700 http://bitbucket.org/pypy/pypy/changeset/e971012143a5/ Log: store (app-level) pyfuncs in a cache and simply callback returns 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 @@ -100,7 +100,9 @@ return obj.space.call_method(w_1, m2) ### TF1 ---------------------------------------------------------------------- -tfn_pyfuncs = {} +class State(object): + def __init__(self, space): + self.tfn_pyfuncs = {} _tfn_install = rffi.llexternal( "cppyy_tfn_install", @@ -138,11 +140,11 @@ raise TypeError("2nd argument is not a valid python callable") fid = _tfn_install(funcname, npar) - tfn_pyfuncs[fid] = pyfunc + state = space.fromcache(State) + state.tfn_pyfuncs[fid] = pyfunc newargs_w = [args_w[1], space.wrap(fid), args_w[3], args_w[4], space.wrap(npar)] except (OperationError, TypeError, IndexError): newargs_w = args_w[1:] # drop class - pass # return control back to the original, unpythonized overload ol = tf1_class.get_overload("TF1") @@ -407,11 +409,12 @@ # TODO: it actually can fail ... @cpython_api([rffi.LONG, rffi.INT, rffi.DOUBLEP, rffi.DOUBLEP], rffi.DOUBLE, error=CANNOT_FAIL) def cppyy_tfn_callback(space, idx, npar, a0, a1): - pyfunc = tfn_pyfuncs[idx] + state = space.fromcache(State) + pyfunc = state.tfn_pyfuncs[idx] npar = int(npar) from pypy.module._rawffi.interp_rawffi import unpack_simple_shape - from pypy.module._rawffi.array import W_Array, W_ArrayInstance + from pypy.module._rawffi.array import W_Array arr = space.interp_w(W_Array, unpack_simple_shape(space, space.wrap('d'))) address = rffi.cast(rffi.ULONG, a0) arg0 = arr.fromaddress(space, address, 4) @@ -422,7 +425,7 @@ result = space.call_function(pyfunc, arg0, arg1) else: result = space.call_function(pyfunc, arg0) + dresult = space.float_w(result) except Exception: - # TODO: error handling here .. - return -1. - return space.float_w(result) + dresult = -1.; # TODO: error handling here .. + return dresult From noreply at buildbot.pypy.org Fri Sep 20 08:36:32 2013 From: noreply at buildbot.pypy.org (wlav) Date: Fri, 20 Sep 2013 08:36:32 +0200 (CEST) Subject: [pypy-commit] pypy reflex-support: merge fix for memcpy into branch Message-ID: <20130920063632.372D71C1387@cobra.cs.uni-duesseldorf.de> Author: Wim Lavrijsen Branch: reflex-support Changeset: r67014:f19f98d0a00a Date: 2013-09-16 11:33 -0700 http://bitbucket.org/pypy/pypy/changeset/f19f98d0a00a/ Log: merge fix for memcpy into branch diff --git a/rpython/rtyper/lltypesystem/rffi.py b/rpython/rtyper/lltypesystem/rffi.py --- a/rpython/rtyper/lltypesystem/rffi.py +++ b/rpython/rtyper/lltypesystem/rffi.py @@ -1138,6 +1138,5 @@ c_memcpy = llexternal("memcpy", [VOIDP, VOIDP, SIZE_T], lltype.Void, - _nowrapper=True, releasegil=False + releasegil=False ) - diff --git a/rpython/rtyper/lltypesystem/test/test_rffi.py b/rpython/rtyper/lltypesystem/test/test_rffi.py --- a/rpython/rtyper/lltypesystem/test/test_rffi.py +++ b/rpython/rtyper/lltypesystem/test/test_rffi.py @@ -810,3 +810,12 @@ assert cast(LONG, x) == 65535 else: assert cast(LONG, cast(INT, x)) == -1 + +def test_c_memcpy(): + p1 = str2charp("hello") + p2 = str2charp("WORLD") + c_memcpy(cast(VOIDP, p2), cast(VOIDP, p1), 3) + assert charp2str(p1) == "hello" + assert charp2str(p2) == "helLD" + free_charp(p1) + free_charp(p2) From noreply at buildbot.pypy.org Fri Sep 20 08:36:33 2013 From: noreply at buildbot.pypy.org (wlav) Date: Fri, 20 Sep 2013 08:36:33 +0200 (CEST) Subject: [pypy-commit] pypy reflex-support: fix coding convention Message-ID: <20130920063633.516D01C30E2@cobra.cs.uni-duesseldorf.de> Author: Wim Lavrijsen Branch: reflex-support Changeset: r67015:cf8cf338d946 Date: 2013-09-16 11:34 -0700 http://bitbucket.org/pypy/pypy/changeset/cf8cf338d946/ Log: fix coding convention 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 @@ -1003,8 +1003,8 @@ (double*)G__int(libp->para[0]), fid_and_npar.second ? (double*)G__int(libp->para[1]) : NULL); // translate result (TODO: error checking) - G__letdouble( res, 100, d ); - return ( 1 || hash || res || libp ); + G__letdouble(res, 100, d); + return (1 || hash || res || libp); } long cppyy_tfn_install(const char* funcname, int npar) { From noreply at buildbot.pypy.org Fri Sep 20 08:36:39 2013 From: noreply at buildbot.pypy.org (wlav) Date: Fri, 20 Sep 2013 08:36:39 +0200 (CEST) Subject: [pypy-commit] pypy reflex-support: error checking Message-ID: <20130920063639.3D98B1C0209@cobra.cs.uni-duesseldorf.de> Author: Wim Lavrijsen Branch: reflex-support Changeset: r67020:1baa635e7d05 Date: 2013-09-18 16:00 -0700 http://bitbucket.org/pypy/pypy/changeset/1baa635e7d05/ Log: error checking 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 @@ -994,11 +994,18 @@ // This is a generic CINT-installable TFN (with N=1,2,3) callback (used to factor // out some common code), to allow TFN to call back into python. - std::pair fid_and_npar = s_tagnum2fid[G__value_get_tagnum(res)]; + std::map >::iterator it = s_tagnum2fid.find(G__value_get_tagnum(res)); + if (it == s_tagnum2fid.end()) { + // TODO: report error here + return 0; + } + + const std::pair& fid_and_npar = it->second; // callback (defined in cint_capi.py) - double d = cppyy_tfn_callback(fid_and_npar.first, fid_and_npar.second, - (double*)G__int(libp->para[0]), fid_and_npar.second ? (double*)G__int(libp->para[1]) : NULL); + double* a0 = (double*)G__int(libp->para[0]); + double* a1 = (double*)(fid_and_npar.second ? G__int(libp->para[1]) : 0); + double d = cppyy_tfn_callback(fid_and_npar.first, fid_and_npar.second, a0, a1); // translate result (TODO: error checking) G__letdouble(res, 100, d); From noreply at buildbot.pypy.org Fri Sep 20 08:36:40 2013 From: noreply at buildbot.pypy.org (wlav) Date: Fri, 20 Sep 2013 08:36:40 +0200 (CEST) Subject: [pypy-commit] pypy reflex-support: o) rewrite of TF1 callbacks, now using _cffi_backend Message-ID: <20130920063640.5962D1C0209@cobra.cs.uni-duesseldorf.de> Author: Wim Lavrijsen Branch: reflex-support Changeset: r67021:f5894d23c106 Date: 2013-09-19 22:55 -0700 http://bitbucket.org/pypy/pypy/changeset/f5894d23c106/ Log: o) rewrite of TF1 callbacks, now using _cffi_backend o) release gil on calls into CINT, but lock CINT itself globally 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 @@ -12,6 +12,7 @@ '_template_byname' : 'interp_cppyy.template_byname', '_std_string_name' : 'interp_cppyy.std_string_name', '_set_class_generator' : 'interp_cppyy.set_class_generator', + '_set_function_generator': 'interp_cppyy.set_function_generator', '_register_class' : 'interp_cppyy.register_class', '_is_static' : 'interp_cppyy.is_static', 'CPPInstance' : 'interp_cppyy.W_CPPInstance', 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 @@ -34,8 +34,8 @@ def identify(): return 'CINT' -ts_reflect = False -ts_call = False +ts_reflect = True +ts_call = True ts_memory = False ts_helper = False @@ -49,13 +49,15 @@ _cintdll = rdynload.dlopen(ll_libname, rdynload.RTLD_GLOBAL | rdynload.RTLD_NOW) with rffi.scoped_str2charp('libCore.so') as ll_libname: _coredll = rdynload.dlopen(ll_libname, rdynload.RTLD_GLOBAL | rdynload.RTLD_NOW) +with rffi.scoped_str2charp('libHist.so') as ll_libname: + _coredll = rdynload.dlopen(ll_libname, rdynload.RTLD_GLOBAL | rdynload.RTLD_NOW) eci = ExternalCompilationInfo( separate_module_files=[srcpath.join("cintcwrapper.cxx")], include_dirs=[incpath] + rootincpath, includes=["cintcwrapper.h"], library_dirs=rootlibpath, - libraries=["Core", "Cint"], + libraries=["Hist", "Core", "Cint"], use_cpp_linker=True, ) @@ -102,11 +104,12 @@ ### TF1 ---------------------------------------------------------------------- class State(object): def __init__(self, space): - self.tfn_pyfuncs = {} + self.tfn_pyfuncs = [] + self.tfn_callbacks = [] -_tfn_install = rffi.llexternal( - "cppyy_tfn_install", - [rffi.CCHARP, rffi.INT], rffi.LONG, +_create_tf1 = rffi.llexternal( + "cppyy_create_tf1", + [rffi.CCHARP, rffi.ULONG, rffi.DOUBLE, rffi.DOUBLE, rffi.INT], C_OBJECT, releasegil=False, compilation_info=eci) @@ -135,15 +138,38 @@ if argc == 6: npar = space.int_w(args_w[5]) # third argument must be a callable python object - pyfunc = args_w[2] - if not space.is_true(space.callable(pyfunc)): + w_callable = args_w[2] + if not space.is_true(space.callable(w_callable)): raise TypeError("2nd argument is not a valid python callable") - fid = _tfn_install(funcname, npar) - state = space.fromcache(State) - state.tfn_pyfuncs[fid] = pyfunc - newargs_w = [args_w[1], space.wrap(fid), args_w[3], args_w[4], space.wrap(npar)] - except (OperationError, TypeError, IndexError): + # generate a pointer to function + from pypy.module._cffi_backend import newtype, ctypefunc, func + + c_double = newtype.new_primitive_type(space, 'double') + c_doublep = newtype.new_pointer_type(space, c_double) + + # wrap the callable as the signature needs modifying + w_ifunc = interp_cppyy.get_interface_func(space, w_callable, npar) + + w_cfunc = ctypefunc.W_CTypeFunc(space, [c_doublep, c_doublep], c_double, False) + w_callback = func.callback(space, w_cfunc, w_ifunc, None) + funcaddr = rffi.cast(rffi.ULONG, w_callback.get_closure()) + + # so far, so good; leaves on issue: CINT is expecting a wrapper, but + # we need the overload that takes a function pointer, which is not in + # the dictionary, hence this helper: + newinst = _create_tf1(space.str_w(args_w[1]), funcaddr, + space.float_w(args_w[3]), space.float_w(args_w[4]), npar) + + from pypy.module.cppyy import interp_cppyy + w_instance = interp_cppyy.wrap_cppobject(space, newinst, tf1_class, + do_cast=False, python_owns=True, fresh=True) + + # tie all the life times to the TF1 instance + space.setattr(w_instance, space.wrap('_callback'), w_callback) + + return w_instance + except (OperationError, TypeError, IndexError), e: newargs_w = args_w[1:] # drop class # return control back to the original, unpythonized overload @@ -404,28 +430,3 @@ if obj is not None: memory_regulator.unregister(obj) obj._rawobject = C_NULL_OBJECT - -# TFn callback (as above: needs better solution, but this is for CINT only) -# TODO: it actually can fail ... - at cpython_api([rffi.LONG, rffi.INT, rffi.DOUBLEP, rffi.DOUBLEP], rffi.DOUBLE, error=CANNOT_FAIL) -def cppyy_tfn_callback(space, idx, npar, a0, a1): - state = space.fromcache(State) - pyfunc = state.tfn_pyfuncs[idx] - npar = int(npar) - - from pypy.module._rawffi.interp_rawffi import unpack_simple_shape - from pypy.module._rawffi.array import W_Array - arr = space.interp_w(W_Array, unpack_simple_shape(space, space.wrap('d'))) - address = rffi.cast(rffi.ULONG, a0) - arg0 = arr.fromaddress(space, address, 4) - try: - if npar != 0: - address = rffi.cast(rffi.ULONG, a1) - arg1 = arr.fromaddress(space, address, npar) - result = space.call_function(pyfunc, arg0, arg1) - else: - result = space.call_function(pyfunc, arg0) - dresult = space.float_w(result) - except Exception: - dresult = -1.; # TODO: error handling here .. - return dresult diff --git a/pypy/module/cppyy/include/cintcwrapper.h b/pypy/module/cppyy/include/cintcwrapper.h --- a/pypy/module/cppyy/include/cintcwrapper.h +++ b/pypy/module/cppyy/include/cintcwrapper.h @@ -11,7 +11,8 @@ void* cppyy_load_dictionary(const char* lib_name); /* pythonization helpers */ - long cppyy_tfn_install(const char* funcname, int npar); + cppyy_object_t cppyy_create_tf1(const char* funcname, unsigned long address, + double xmin, double xmax, int npar); cppyy_object_t cppyy_ttree_Branch( void* vtree, const char* branchname, const char* classname, 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 @@ -101,6 +101,11 @@ state = space.fromcache(State) state.w_clgen_callback = w_callback + at unwrap_spec(w_callback=W_Root) +def set_function_generator(space, w_callback): + state = space.fromcache(State) + state.w_fngen_callback = w_callback + def register_class(space, w_pycppclass): w_cppclass = space.findattr(w_pycppclass, space.wrap("_cpp_proxy")) cppclass = space.interp_w(W_CPPClass, w_cppclass, can_be_None=False) @@ -1137,6 +1142,10 @@ w_pycppclass = space.call_function(state.w_clgen_callback, space.wrap(final_name)) return w_pycppclass +def get_interface_func(space, w_callable, npar): + state = space.fromcache(State) + return space.call_function(state.w_fngen_callback, w_callable, space.wrap(npar)) + def wrap_cppobject(space, rawobject, cppclass, do_cast=True, python_owns=False, is_ref=False, fresh=False): rawobject = rffi.cast(capi.C_OBJECT, rawobject) 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 @@ -55,6 +55,19 @@ def clgen_callback(name): return get_pycppclass(name) +def fngen_callback(func, npar): # todo, some kind of arg transform spec + if npar == 0: + def wrapper(a0, a1): + la0 = [a0[0], a0[1], a0[2], a0[3]] + return func(la0) + return wrapper + else: + def wrapper(a0, a1): + la0 = [a0[0], a0[1], a0[2], a0[3]] + la1 = [a1[i] for i in range(npar)] + return func(la0, la1) + return wrapper + def make_static_function(func_name, cppol): def function(*args): @@ -416,6 +429,9 @@ # class generator callback cppyy._set_class_generator(clgen_callback) + # function generator callback + cppyy._set_function_generator(fngen_callback) + # user interface objects (note the two-step of not calling scope_byname here: # creation of global functions may cause the creation of classes in the global # namespace, so gbl must exist at that point to cache them) 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 @@ -25,6 +25,7 @@ // for pythonization #include "TTree.h" #include "TBranch.h" +#include "TF1.h" #include "TString.h" #include "Api.h" @@ -59,12 +60,9 @@ TList* fAllPubMethod; //all public methods (including from base classes) }; -// memory regulation (cppyy_recursive_remove is generated a la cpyext capi calls) +// memory regulation (cppyy_recursive_remove is generated as a cpyext capi call) extern "C" void cppyy_recursive_remove(void*); -// TFN callback helper (generated a la cpyext capi calls) -extern "C" double cppyy_tfn_callback(long, int, double*, double*); - class Cppyy_MemoryRegulator : public TObject { public: virtual void RecursiveRemove(TObject* object) { @@ -240,6 +238,7 @@ /* name to opaque C++ scope representation -------------------------------- */ int cppyy_num_scopes(cppyy_scope_t handle) { + R__LOCKGUARD2(gCINTMutex); TClassRef& cr = type_from_handle(handle); if (cr.GetClass()) { /* not supported as CINT does not store classes hierarchically */ @@ -249,6 +248,7 @@ } char* cppyy_scope_name(cppyy_scope_t handle, int iscope) { + R__LOCKGUARD2(gCINTMutex); TClassRef& cr = type_from_handle(handle); if (cr.GetClass()) { /* not supported as CINT does not store classes hierarchically */ @@ -262,6 +262,7 @@ } char* cppyy_resolve_name(const char* cppitem_name) { + R__LOCKGUARD2(gCINTMutex); std::string tname = cppitem_name; // global namespace? @@ -294,6 +295,8 @@ } cppyy_scope_t cppyy_get_scope(const char* scope_name) { + R__LOCKGUARD2(gCINTMutex); + // CINT still has trouble with std:: sometimes ... if (strncmp(scope_name, "std::", 5) == 0) scope_name = &scope_name[5]; @@ -323,6 +326,8 @@ } cppyy_type_t cppyy_get_template(const char* template_name) { + R__LOCKGUARD2(gCINTMutex); + ClassRefIndices_t::iterator icr = g_classref_indices.find(template_name); if (icr != g_classref_indices.end()) return (cppyy_type_t)icr->second; @@ -342,6 +347,7 @@ } cppyy_type_t cppyy_actual_class(cppyy_type_t klass, cppyy_object_t obj) { + R__LOCKGUARD2(gCINTMutex); TClassRef& cr = type_from_handle(klass); TClass* clActual = cr->GetActualClass( (void*)obj ); if (clActual && clActual != cr.GetClass()) { @@ -354,6 +360,7 @@ /* memory management ------------------------------------------------------ */ cppyy_object_t cppyy_allocate(cppyy_type_t handle) { + R__LOCKGUARD2(gCINTMutex); TClassRef& cr = type_from_handle(handle); return (cppyy_object_t)malloc(cr->Size()); } @@ -363,6 +370,7 @@ } void cppyy_destruct(cppyy_type_t handle, cppyy_object_t self) { + R__LOCKGUARD2(gCINTMutex); TClassRef& cr = type_from_handle(handle); cr->Destructor((void*)self, true); } @@ -372,6 +380,8 @@ static inline G__value cppyy_call_T(cppyy_method_t method, cppyy_object_t self, int nargs, void* args) { + R__LOCKGUARD2(gCINTMutex); + G__param* libp = (G__param*)((char*)args - offsetof(G__param, para)); assert(libp->paran == nargs); fixup_args(libp); @@ -469,6 +479,7 @@ } char* cppyy_call_s(cppyy_method_t method, cppyy_object_t self, int nargs, void* args) { + R__LOCKGUARD2(gCINTMutex); G__value result = cppyy_call_T(method, self, nargs, args); G__pop_tempobject_nodel(); if (result.ref && *(long*)result.ref) { @@ -480,6 +491,7 @@ } cppyy_object_t cppyy_constructor(cppyy_method_t method, cppyy_type_t handle, int nargs, void* args) { + R__LOCKGUARD2(gCINTMutex); cppyy_object_t self = (cppyy_object_t)NULL; if ((InterpretedFuncs_t::size_type)method >= g_interpreted.size()) { G__setgvp((long)G__PVOID); @@ -496,6 +508,7 @@ cppyy_object_t cppyy_call_o(cppyy_type_t method, cppyy_object_t self, int nargs, void* args, cppyy_type_t /*result_type*/ ) { + R__LOCKGUARD2(gCINTMutex); G__value result = cppyy_call_T(method, self, nargs, args); G__pop_tempobject_nodel(); return G__int(result); @@ -532,6 +545,7 @@ /* scope reflection information ------------------------------------------- */ int cppyy_is_namespace(cppyy_scope_t handle) { + R__LOCKGUARD2(gCINTMutex); TClassRef& cr = type_from_handle(handle); if (cr.GetClass() && cr->GetClassInfo()) return cr->Property() & G__BIT_ISNAMESPACE; @@ -541,6 +555,7 @@ } int cppyy_is_enum(const char* type_name) { + R__LOCKGUARD2(gCINTMutex); G__TypeInfo ti(type_name); return (ti.Property() & G__BIT_ISENUM); } @@ -548,6 +563,7 @@ /* type/class reflection information -------------------------------------- */ char* cppyy_final_name(cppyy_type_t handle) { + R__LOCKGUARD2(gCINTMutex); TClassRef& cr = type_from_handle(handle); if (cr.GetClass() && cr->GetClassInfo()) { std::string true_name = G__TypeInfo(cr->GetName()).TrueName(); @@ -560,6 +576,7 @@ } char* cppyy_scoped_final_name(cppyy_type_t handle) { + R__LOCKGUARD2(gCINTMutex); TClassRef& cr = type_from_handle(handle); if (cr.GetClass() && cr->GetClassInfo()) { std::string true_name = G__TypeInfo(cr->GetName()).TrueName(); @@ -575,6 +592,7 @@ } int cppyy_num_bases(cppyy_type_t handle) { + R__LOCKGUARD2(gCINTMutex); TClassRef& cr = type_from_handle(handle); if (cr.GetClass() && cr->GetListOfBases() != 0) return cr->GetListOfBases()->GetSize(); @@ -582,12 +600,14 @@ } char* cppyy_base_name(cppyy_type_t handle, int base_index) { + R__LOCKGUARD2(gCINTMutex); TClassRef& cr = type_from_handle(handle); TBaseClass* b = (TBaseClass*)cr->GetListOfBases()->At(base_index); return type_cppstring_to_cstring(b->GetName()); } int cppyy_is_subtype(cppyy_type_t derived_handle, cppyy_type_t base_handle) { + R__LOCKGUARD2(gCINTMutex); TClassRef& derived_type = type_from_handle(derived_handle); TClassRef& base_type = type_from_handle(base_handle); return derived_type->GetBaseClass(base_type) != 0; @@ -595,6 +615,8 @@ size_t cppyy_base_offset(cppyy_type_t derived_handle, cppyy_type_t base_handle, cppyy_object_t address, int /* direction */) { + R__LOCKGUARD2(gCINTMutex); + // WARNING: CINT can not handle actual dynamic casts! TClassRef& derived_type = type_from_handle(derived_handle); TClassRef& base_type = type_from_handle(base_handle); @@ -626,6 +648,7 @@ /* method/function reflection information --------------------------------- */ int cppyy_num_methods(cppyy_scope_t handle) { + R__LOCKGUARD2(gCINTMutex); TClassRef& cr = type_from_handle(handle); if (cr.GetClass() && cr->GetListOfMethods()) return cr->GetListOfMethods()->GetSize(); @@ -648,6 +671,7 @@ } cppyy_index_t cppyy_method_index_at(cppyy_scope_t handle, int imeth) { + R__LOCKGUARD2(gCINTMutex); TClassRef& cr = type_from_handle(handle); if (cr.GetClass()) return (cppyy_index_t)imeth; @@ -655,6 +679,8 @@ } cppyy_index_t* cppyy_method_indices_from_name(cppyy_scope_t handle, const char* name) { + R__LOCKGUARD2(gCINTMutex); + std::vector result; TClassRef& cr = type_from_handle(handle); if (cr.GetClass()) { @@ -694,6 +720,7 @@ char* cppyy_method_name(cppyy_scope_t handle, cppyy_index_t idx) { + R__LOCKGUARD2(gCINTMutex); TFunction* f = type_get_method(handle, idx); std::string name = f->GetName(); TClassRef& cr = type_from_handle(handle); @@ -705,6 +732,7 @@ } char* cppyy_method_result_type(cppyy_scope_t handle, cppyy_index_t idx) { + R__LOCKGUARD2(gCINTMutex); TClassRef& cr = type_from_handle(handle); if (cr.GetClass() && cppyy_is_constructor(handle, idx)) return cppstring_to_cstring("constructor"); @@ -713,16 +741,19 @@ } int cppyy_method_num_args(cppyy_scope_t handle, cppyy_index_t idx) { + R__LOCKGUARD2(gCINTMutex); TFunction* f = type_get_method(handle, idx); return f->GetNargs(); } int cppyy_method_req_args(cppyy_scope_t handle, cppyy_index_t idx) { + R__LOCKGUARD2(gCINTMutex); TFunction* f = type_get_method(handle, idx); return f->GetNargs() - f->GetNargsOpt(); } char* cppyy_method_arg_type(cppyy_scope_t handle, cppyy_index_t idx, int arg_index) { + R__LOCKGUARD2(gCINTMutex); TFunction* f = type_get_method(handle, idx); TMethodArg* arg = (TMethodArg*)f->GetListOfMethodArgs()->At(arg_index); return type_cppstring_to_cstring(arg->GetFullTypeName()); @@ -734,6 +765,7 @@ } char* cppyy_method_signature(cppyy_scope_t handle, cppyy_index_t idx) { + R__LOCKGUARD2(gCINTMutex); TClassRef& cr = type_from_handle(handle); TFunction* f = type_get_method(handle, idx); std::ostringstream sig; @@ -753,6 +785,7 @@ int cppyy_method_is_template(cppyy_scope_t handle, cppyy_index_t idx) { + R__LOCKGUARD2(gCINTMutex); TClassRef& cr = type_from_handle(handle); TFunction* f = type_get_method(handle, idx); std::string name = f->GetName(); @@ -766,6 +799,7 @@ char* cppyy_method_template_arg_name( cppyy_scope_t handle, cppyy_index_t idx, cppyy_index_t /*iarg*/) { + R__LOCKGUARD2(gCINTMutex); // TODO: return only the name for the requested arg TClassRef& cr = type_from_handle(handle); TFunction* f = type_get_method(handle, idx); @@ -776,6 +810,8 @@ cppyy_method_t cppyy_get_method(cppyy_scope_t handle, cppyy_index_t idx) { + R__LOCKGUARD2(gCINTMutex); + TClassRef& cr = type_from_handle(handle); TFunction* f = type_get_method(handle, idx); if (cr && cr.GetClass() && !cr->IsLoaded()) { @@ -800,6 +836,8 @@ } cppyy_index_t cppyy_get_global_operator(cppyy_scope_t scope, cppyy_scope_t lc, cppyy_scope_t rc, const char* op) { + R__LOCKGUARD2(gCINTMutex); + TClassRef& lccr = type_from_handle(lc); TClassRef& rccr = type_from_handle(rc); @@ -831,12 +869,14 @@ /* method properties ----------------------------------------------------- */ int cppyy_is_constructor(cppyy_type_t handle, cppyy_index_t idx) { + R__LOCKGUARD2(gCINTMutex); TClassRef& cr = type_from_handle(handle); TMethod* m = (TMethod*)cr->GetListOfMethods()->At(idx); return strcmp(m->GetName(), ((G__ClassInfo*)cr->GetClassInfo())->Name()) == 0; } int cppyy_is_staticmethod(cppyy_type_t handle, cppyy_index_t idx) { + R__LOCKGUARD2(gCINTMutex); TClassRef& cr = type_from_handle(handle); TMethod* m = (TMethod*)cr->GetListOfMethods()->At(idx); return m->Property() & G__BIT_ISSTATIC; @@ -845,6 +885,8 @@ /* data member reflection information ------------------------------------- */ int cppyy_num_datamembers(cppyy_scope_t handle) { + R__LOCKGUARD2(gCINTMutex); + TClassRef& cr = type_from_handle(handle); if (cr.GetClass() && cr->GetListOfDataMembers()) return cr->GetListOfDataMembers()->GetSize(); @@ -867,6 +909,8 @@ } char* cppyy_datamember_name(cppyy_scope_t handle, int datamember_index) { + R__LOCKGUARD2(gCINTMutex); + TClassRef& cr = type_from_handle(handle); if (cr.GetClass()) { TDataMember* m = (TDataMember*)cr->GetListOfDataMembers()->At(datamember_index); @@ -877,6 +921,8 @@ } char* cppyy_datamember_type(cppyy_scope_t handle, int datamember_index) { + R__LOCKGUARD2(gCINTMutex); + TClassRef& cr = type_from_handle(handle); if (cr.GetClass()) { TDataMember* m = (TDataMember*)cr->GetListOfDataMembers()->At(datamember_index); @@ -895,6 +941,7 @@ } size_t cppyy_datamember_offset(cppyy_scope_t handle, int datamember_index) { + R__LOCKGUARD2(gCINTMutex); TClassRef& cr = type_from_handle(handle); if (cr.GetClass()) { TDataMember* m = (TDataMember*)cr->GetListOfDataMembers()->At(datamember_index); @@ -905,6 +952,8 @@ } int cppyy_datamember_index(cppyy_scope_t handle, const char* name) { + R__LOCKGUARD2(gCINTMutex); + TClassRef& cr = type_from_handle(handle); if (cr.GetClass()) { // called from updates; add a hard reset as the code itself caches in @@ -940,6 +989,7 @@ /* data member properties ------------------------------------------------ */ int cppyy_is_publicdata(cppyy_scope_t handle, int datamember_index) { + R__LOCKGUARD2(gCINTMutex); TClassRef& cr = type_from_handle(handle); if (cr.GetClass()) { TDataMember* m = (TDataMember*)cr->GetListOfDataMembers()->At(datamember_index); @@ -949,6 +999,7 @@ } int cppyy_is_staticdata(cppyy_scope_t handle, int datamember_index) { + R__LOCKGUARD2(gCINTMutex); TClassRef& cr = type_from_handle(handle); if (cr.GetClass()) { TDataMember* m = (TDataMember*)cr->GetListOfDataMembers()->At(datamember_index); @@ -981,6 +1032,7 @@ void* cppyy_load_dictionary(const char* lib_name) { + R__LOCKGUARD2(gCINTMutex); if (0 <= gSystem->Load(lib_name)) return (void*)1; return (void*)0; @@ -988,66 +1040,11 @@ /* pythonization helpers -------------------------------------------------- */ -static std::map > s_tagnum2fid; +typedef double (*tfn_callback)(double*, double*); -static int TFNPyCallback(G__value* res, G__CONST char*, struct G__param* libp, int hash) { - // This is a generic CINT-installable TFN (with N=1,2,3) callback (used to factor - // out some common code), to allow TFN to call back into python. - - std::map >::iterator it = s_tagnum2fid.find(G__value_get_tagnum(res)); - if (it == s_tagnum2fid.end()) { - // TODO: report error here - return 0; - } - - const std::pair& fid_and_npar = it->second; - - // callback (defined in cint_capi.py) - double* a0 = (double*)G__int(libp->para[0]); - double* a1 = (double*)(fid_and_npar.second ? G__int(libp->para[1]) : 0); - double d = cppyy_tfn_callback(fid_and_npar.first, fid_and_npar.second, a0, a1); - - // translate result (TODO: error checking) - G__letdouble(res, 100, d); - return (1 || hash || res || libp); -} - -long cppyy_tfn_install(const char* funcname, int npar) { - // make a new function placeholder known to CINT - static Long_t s_fid = (Long_t)cppyy_tfn_install; // ensures no user function lives there - ++s_fid; - - const char* signature = "D - - 0 - - D - - 0 - -"; - - // create a return type (typically masked/wrapped by a TPyReturn) for the method - G__linked_taginfo pti; - pti.tagnum = -1; - pti.tagtype = 'c'; - std::string tagname("::py_"); // used as a buffer - tagname += funcname; - pti.tagname = tagname.c_str(); - int tagnum = G__get_linked_tagnum(&pti); // creates entry for new names - - // for free functions, add to global scope and add lookup through tp2f - // setup a connection between the pointer and the name - Long_t hash = 0, len = 0; - G__hash(funcname, hash, len); - G__lastifuncposition(); - G__memfunc_setup(funcname, hash, (G__InterfaceMethod)&TFNPyCallback, - tagnum, tagnum, tagnum, 0, 2, 0, 1, 0, signature, - (char*)0, (void*)s_fid, 0); - G__resetifuncposition(); - - // setup a name in the global namespace (does not result in calls, so the signature - // does not matter; but it makes subsequent GetMethod() calls work) - G__MethodInfo meth = G__ClassInfo().AddMethod( - funcname, funcname, signature, 1, 0, (void*)&TFNPyCallback); - - // store mapping so that the callback can find it - s_tagnum2fid[tagnum] = std::make_pair(s_fid, npar); - - // hard to check result ... assume ok - return s_fid; +cppyy_object_t cppyy_create_tf1(const char* funcname, unsigned long address, + double xmin, double xmax, int npar) { + return (cppyy_object_t)new TF1(funcname, (tfn_callback)address, xmin, xmax, npar); } cppyy_object_t cppyy_ttree_Branch(void* vtree, const char* branchname, const char* classname, 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 @@ -456,6 +456,8 @@ assert f.Eval(0.5) == 0.5 + del f # force here, to prevent leak-check complaints + def test02_callable_object_callback(self): """Test callback of a python callable object""" @@ -472,6 +474,8 @@ assert f.Eval(-0.1) == 4.8 assert f.Eval(1.3) == 7.6 + del f # force here, to prevent leak-check complaints + def test03_fit_with_python_gaussian(self): """Test fitting with a python global function""" @@ -507,6 +511,8 @@ assert round(result[1] - 0., 1) == 0 # mean assert round(result[2] - 1., 1) == 0 # s.d. + del f # force here, to prevent leak-check complaints + class AppTestSURPLUS: spaceconfig = dict(usemodules=['cppyy', '_rawffi', '_ffi', 'itertools']) From noreply at buildbot.pypy.org Fri Sep 20 08:36:41 2013 From: noreply at buildbot.pypy.org (wlav) Date: Fri, 20 Sep 2013 08:36:41 +0200 (CEST) Subject: [pypy-commit] pypy reflex-support: fix rtyper warning Message-ID: <20130920063641.6525E1C0209@cobra.cs.uni-duesseldorf.de> Author: Wim Lavrijsen Branch: reflex-support Changeset: r67022:ba7094becd52 Date: 2013-09-19 22:55 -0700 http://bitbucket.org/pypy/pypy/changeset/ba7094becd52/ Log: fix rtyper warning 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 @@ -43,6 +43,7 @@ self.cpptemplate_cache = {} self.cppclass_registry = {} self.w_clgen_callback = None + self.w_fngen_callback = None @unwrap_spec(name=str) def resolve_name(space, name): From noreply at buildbot.pypy.org Fri Sep 20 12:08:32 2013 From: noreply at buildbot.pypy.org (mattip) Date: Fri, 20 Sep 2013 12:08:32 +0200 (CEST) Subject: [pypy-commit] pypy pypy-pyarray: merge default into branch Message-ID: <20130920100832.CDAEE1C3412@cobra.cs.uni-duesseldorf.de> Author: Matti Picus Branch: pypy-pyarray Changeset: r67024:5b21bc5371ad Date: 2013-09-20 07:51 +0300 http://bitbucket.org/pypy/pypy/changeset/5b21bc5371ad/ Log: merge default into branch 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 @@ -394,9 +394,12 @@ def setitem_filter(arr, index, value, size): arr_iter = arr.create_iter() - index_iter = index.create_iter(arr.get_shape()) + 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() value_iter = value.create_iter([size]) - shapelen = len(arr.get_shape()) index_dtype = index.get_dtype() arr_dtype = arr.get_dtype() while not index_iter.done(): From noreply at buildbot.pypy.org Fri Sep 20 12:08:31 2013 From: noreply at buildbot.pypy.org (mattip) Date: Fri, 20 Sep 2013 12:08:31 +0200 (CEST) Subject: [pypy-commit] pypy default: copy logic from getitem_filter to setitem_filter Message-ID: <20130920100831.371041C3409@cobra.cs.uni-duesseldorf.de> Author: Matti Picus Branch: Changeset: r67023:c5b518756cc3 Date: 2013-09-20 07:50 +0300 http://bitbucket.org/pypy/pypy/changeset/c5b518756cc3/ Log: copy logic from getitem_filter to setitem_filter 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 @@ -374,9 +374,12 @@ def setitem_filter(arr, index, value, size): arr_iter = arr.create_iter() - index_iter = index.create_iter(index.get_shape()) + 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() value_iter = value.create_iter([size]) - shapelen = len(arr.get_shape()) index_dtype = index.get_dtype() arr_dtype = arr.get_dtype() while not index_iter.done(): From noreply at buildbot.pypy.org Fri Sep 20 12:08:34 2013 From: noreply at buildbot.pypy.org (mattip) Date: Fri, 20 Sep 2013 12:08:34 +0200 (CEST) Subject: [pypy-commit] pypy pypy-pyarray: test numpy.__all__, numpy.get_include() Message-ID: <20130920100834.2818E1C3409@cobra.cs.uni-duesseldorf.de> Author: Matti Picus Branch: pypy-pyarray Changeset: r67025:665e8edf7ca1 Date: 2013-09-20 08:59 +0300 http://bitbucket.org/pypy/pypy/changeset/665e8edf7ca1/ Log: test numpy.__all__, numpy.get_include() diff --git a/TODO.txt b/TODO.txt --- a/TODO.txt +++ b/TODO.txt @@ -1,7 +1,6 @@ TODO list by mattip =================== -- test "from numpypy import *" esp. get_include() - test all *.h files under pypy/module/cpyext/include/numpy - make sure copy_header_files() in api.py is used in package.py - test, implement use of __array_prepare__() diff --git a/lib_pypy/numpy.py b/lib_pypy/numpy.py --- a/lib_pypy/numpy.py +++ b/lib_pypy/numpy.py @@ -7,5 +7,6 @@ UserWarning) # XXX is this the best warning type? from numpypy import * - - +import numpypy +__all__ = numpypy.__all__ +del numpypy diff --git a/pypy/module/test_lib_pypy/numpypy/test_numpy.py b/pypy/module/test_lib_pypy/numpypy/test_numpy.py --- a/pypy/module/test_lib_pypy/numpypy/test_numpy.py +++ b/pypy/module/test_lib_pypy/numpypy/test_numpy.py @@ -31,7 +31,9 @@ import sys from warnings import catch_warnings # XXX why are numpypy and numpy modules already imported? - print sys.modules.keys() + mods = [d for d in sys.modules.keys() if d.find('numpy') >= 0] + if mods: + skip('%s already imported' % mods) with catch_warnings(record=True) as w: import numpy @@ -91,3 +93,14 @@ assert numpypy.PZERO == numpypy.NZERO == 0.0 assert math.isinf(numpypy.inf) assert math.isnan(numpypy.nan) + + def test___all__(self): + import numpy + assert '__all__' in numpy + assert 'numpypy' not in dir(numpy) + + def test_get_include(self): + import numpy, os + assert 'get_include' in dir(numpy) + path = numpy.get_include() + assert os.path.exists(path + '/numpy/arrayobject.h') From noreply at buildbot.pypy.org Fri Sep 20 12:08:35 2013 From: noreply at buildbot.pypy.org (mattip) Date: Fri, 20 Sep 2013 12:08:35 +0200 (CEST) Subject: [pypy-commit] pypy pypy-pyarray: cleanup, add failing test Message-ID: <20130920100835.7BF171C3409@cobra.cs.uni-duesseldorf.de> Author: Matti Picus Branch: pypy-pyarray Changeset: r67026:b45fecb37ac5 Date: 2013-09-20 09:21 +0300 http://bitbucket.org/pypy/pypy/changeset/b45fecb37ac5/ Log: cleanup, add failing test diff --git a/pypy/tool/release/test/nightly.xml b/pypy/tool/release/test/nightly.xml deleted file mode 100644 --- a/pypy/tool/release/test/nightly.xml +++ /dev/null @@ -1,143 +0,0 @@ - - -Directory listing for /nightly/trunk/ - - - - -

    Directory listing for /nightly/trunk/

    - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
    FilenameSizeDateown testsapplevel tests
    pypy-c-jit-40170-c407c9dc5382-linux.tar.bz28M2010-12-2216561, 1 F, 2089 s, 4 x3488, 0 F, 1542 s, 1 x
    pypy-c-jit-40170-c407c9dc5382-linux64.tar.bz29M2010-12-2216216, 3 F, 2417 s, 4 x3483, 0 F, 1547 s, 1 x
    pypy-c-jit-40170-c407c9dc5382-osx64.tar.bz210M2010-12-22NoneNone
    pypy-c-nojit-40170-c407c9dc5382-linux.tar.bz27M2010-12-2216561, 1 F, 2089 s, 4 x3377, 0 F, 1542 s, 1 x
    pypy-c-nojit-40170-c407c9dc5382-linux64.tar.bz28M2010-12-2216216, 3 F, 2417 s, 4 x3372, 0 F, 1547 s, 1 x
    pypy-c-stackless-40170-c407c9dc5382-linux.tar.bz210M2010-12-2216561, 1 F, 2089 s, 4 x3221, 0 F, 1401 s, 1 x
    pypy-c-jit-40149-cd083843b67a-linux.tar.bz210M2010-12-2116561, 0 F, 2088 s, 4 x3488, 0 F, 1542 s, 1 x
    pypy-c-jit-40149-cd083843b67a-linux64.tar.bz211M2010-12-2116219, 0 F, 2415 s, 4 x3483, 0 F, 1547 s, 1 x
    pypy-c-nojit-40149-cd083843b67a-linux.tar.bz27M2010-12-2116561, 0 F, 2088 s, 4 x3377, 0 F, 1542 s, 1 x
    pypy-c-nojit-40149-cd083843b67a-linux64.tar.bz29M2010-12-2116219, 0 F, 2415 s, 4 x3372, 0 F, 1547 s, 1 x
    pypy-c-stackless-40149-cd083843b67a-linux.tar.bz210M2010-12-2116561, 0 F, 2088 s, 4 x
    - - - 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 @@ -3,7 +3,7 @@ from pypy.conftest import pypydir from pypy.tool.release import package from pypy.module.sys.version import CPYTHON_VERSION -import tarfile, zipfile, os, sys +import tarfile, zipfile, sys def test_dir_structure(test='test'): # make sure we have sort of pypy-c @@ -61,9 +61,12 @@ assert zh.open(member) else: assert th.getmember(member) + else: + print 'include file "%s" not found, are we translated?' % includedir.join(name) check_include('Python.h') check_include('modsupport.h') check_include('pypy_decl.h') + check_include('numpy/arrayobject.h') finally: if fake_pypy_c: pypy_c.remove() From noreply at buildbot.pypy.org Fri Sep 20 12:08:36 2013 From: noreply at buildbot.pypy.org (mattip) Date: Fri, 20 Sep 2013 12:08:36 +0200 (CEST) Subject: [pypy-commit] pypy pypy-pyarray: use copytree to fix recursive copying of headers Message-ID: <20130920100836.8FE3D1C3409@cobra.cs.uni-duesseldorf.de> Author: Matti Picus Branch: pypy-pyarray Changeset: r67027:5e24c1bb9881 Date: 2013-09-20 10:04 +0300 http://bitbucket.org/pypy/pypy/changeset/5e24c1bb9881/ Log: use copytree to fix recursive copying of headers 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 @@ -86,6 +86,13 @@ builddir = udir.ensure("build", dir=True) pypydir = builddir.ensure(name, dir=True) includedir = basedir.join('include') + # Recursively copy all headers, shutil has only ignore + # so we do a double-negative to include what we want + def copyonly(dirpath, contents): + return set(contents) - set( + shutil.ignore_patterns('*.h', '*.incl')(dirpath, contents), + ) + shutil.copytree(str(includedir), str(pypydir.join('include'))) pypydir.ensure('include', dir=True) if sys.platform == 'win32': @@ -116,7 +123,7 @@ # modules for windows, has the lib moved or are there no # exported functions in the dll so no import library is created? - # Careful: to copy lib_pypy, copying just the svn-tracked files + # Careful: to copy lib_pypy, copying just the hg-tracked files # would not be enough: there are also ctypes_config_cache/_*_cache.py. shutil.copytree(str(basedir.join('lib-python').join(STDLIB_VER)), str(pypydir.join('lib-python').join(STDLIB_VER)), @@ -127,11 +134,6 @@ '*.c', '*.o')) for file in ['LICENSE', 'README.rst']: shutil.copy(str(basedir.join(file)), str(pypydir)) - headers = includedir.listdir('*.h') + includedir.listdir('*.inl') - for n in headers: - # we want to put there all *.h and *.inl from trunk/include - # and from pypy/_interfaces - shutil.copy(str(n), str(pypydir.join('include'))) # spdir = pypydir.ensure('site-packages', dir=True) shutil.copy(str(basedir.join('site-packages', 'README')), str(spdir)) From noreply at buildbot.pypy.org Fri Sep 20 12:08:37 2013 From: noreply at buildbot.pypy.org (mattip) Date: Fri, 20 Sep 2013 12:08:37 +0200 (CEST) Subject: [pypy-commit] pypy pypy-pyarray: 'update' TODO (not really checking _all_ the arrayobject.h macros) Message-ID: <20130920100837.D613B1C3409@cobra.cs.uni-duesseldorf.de> Author: Matti Picus Branch: pypy-pyarray Changeset: r67028:a70e6296ea92 Date: 2013-09-20 11:19 +0300 http://bitbucket.org/pypy/pypy/changeset/a70e6296ea92/ Log: 'update' TODO (not really checking _all_ the arrayobject.h macros) diff --git a/TODO.txt b/TODO.txt --- a/TODO.txt +++ b/TODO.txt @@ -1,7 +1,5 @@ TODO list by mattip =================== -- test all *.h files under pypy/module/cpyext/include/numpy -- make sure copy_header_files() in api.py is used in package.py - test, implement use of __array_prepare__() - test, implement use of __array_wrap__() From noreply at buildbot.pypy.org Fri Sep 20 12:08:39 2013 From: noreply at buildbot.pypy.org (mattip) Date: Fri, 20 Sep 2013 12:08:39 +0200 (CEST) Subject: [pypy-commit] pypy pypy-pyarray: add tests for __array_prepare__, __array_wrap__ Message-ID: <20130920100839.BAEC31C3409@cobra.cs.uni-duesseldorf.de> Author: Matti Picus Branch: pypy-pyarray Changeset: r67029:61c630f73ba3 Date: 2013-09-20 11:50 +0300 http://bitbucket.org/pypy/pypy/changeset/61c630f73ba3/ Log: add tests for __array_prepare__, __array_wrap__ diff --git a/pypy/module/micronumpy/test/test_subtype.py b/pypy/module/micronumpy/test/test_subtype.py --- a/pypy/module/micronumpy/test/test_subtype.py +++ b/pypy/module/micronumpy/test/test_subtype.py @@ -244,3 +244,31 @@ assert isinstance(b, D) c = array(a, float) assert c.dtype is dtype(float) + + def test___array_wrap__(self): + from numpypy import ndarray, add, ones + class with_wrap(object): + called_wrap = False + def __array__(self): + return ones(1) + def __array_wrap__(self, arr, context): + self.called_wrap = True + return arr + a = with_wrap() + x = add(a, a) + assert x == 2 + assert type(x) == ndarray + assert a.called_wrap + + def test___array_prepare__(self): + from numpypy import ndarray, array, add, ones + class with_prepare(ndarray): + called_prepare = False + def __array_prepare__(self, arr, context): + self.called_prepare = True + return array(arr).view(type=with_prepare) + a = array(1).view(type=with_prepare) + x = add(a, a) + assert x == 2 + assert type(x) == with_prepare + assert a.called_prepare From noreply at buildbot.pypy.org Fri Sep 20 12:08:41 2013 From: noreply at buildbot.pypy.org (mattip) Date: Fri, 20 Sep 2013 12:08:41 +0200 (CEST) Subject: [pypy-commit] pypy pypy-pyarray: start to implement __array_prepare__ and test failures Message-ID: <20130920100841.3BE871C3409@cobra.cs.uni-duesseldorf.de> Author: Matti Picus Branch: pypy-pyarray Changeset: r67030:b95fcd12507d Date: 2013-09-20 13:04 +0300 http://bitbucket.org/pypy/pypy/changeset/b95fcd12507d/ Log: start to implement __array_prepare__ and test failures 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 @@ -86,7 +86,7 @@ return W_NDimArray(scalar.Scalar(dtype, w_val)) -def convert_to_array(space, w_obj): +def convert_to_array(space, w_obj, use_prepare=False): #XXX: This whole routine should very likely simply be array() from pypy.module.micronumpy.interp_numarray import array from pypy.module.micronumpy import interp_ufuncs @@ -101,7 +101,7 @@ if isinstance(w_result, W_NDimArray): return w_result else: - raise OperationError(space.w_ValueError, + raise OperationError(space.w_ValueError, space.wrap("object __array__ method not producing an array")) elif issequence_w(space, w_obj): # Convert to 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 @@ -437,7 +437,7 @@ # stub implementation of __array__() return self - def descr___array_prepare__(self, space, w_array): + def descr___array_prepare__(self, space, w_array, w_context): # stub implementation of __array_prepare__() if isinstance(w_array, W_NDimArray): return w_array 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 @@ -319,6 +319,22 @@ else: self.done_func = None + def call_prepare(self, space, w_out, w_obj, w_result): + if isinstance(w_out, W_NDimArray): + w_array = space.lookup(w_out, "__array_prepare__") + w_caller = w_out + else: + w_array = space.lookup(w_obj, "__array_prepare__") + w_caller = w_obj + if w_array: + w_result = space.get_and_call_function(w_array, w_caller, w_result, None) + if not isinstance(w_result, W_NDimArray): + raise OperationError(space.w_ValueError, + space.wrap("object __array_prepare__ method not" + " producing an array")) + return w_result + + @jit.unroll_safe def call(self, space, args_w): if len(args_w) > 2: @@ -351,11 +367,11 @@ "ufunc '%s' not supported for the input types" % self.name)) if space.is_none(w_out): out = None - elif not isinstance(w_out, W_NDimArray): - raise OperationError(space.w_TypeError, space.wrap( - 'output must be an array')) + #elif not isinstance(w_out, W_NDimArray): + # raise OperationError(space.w_TypeError, space.wrap( + # 'output must be an array')) else: - out = w_out + out = convert_to_array(space, w_out) calc_dtype = out.get_dtype() if self.comparison_func: res_dtype = interp_dtype.get_dtype_cache(space).w_booldtype @@ -371,14 +387,13 @@ out.set_scalar_value(arr) else: out.fill(arr) - else: - out = arr - return out + return self.call_prepare(space, out, w_lhs, arr) new_shape = shape_agreement(space, w_lhs.get_shape(), w_rhs) new_shape = shape_agreement(space, new_shape, out, broadcast_down=False) - return loop.call2(space, new_shape, self.func, calc_dtype, + w_result = loop.call2(space, new_shape, self.func, calc_dtype, res_dtype, w_lhs, w_rhs, out) - + # XXX handle array_priority + return self.call_prepare(space, out, w_lhs, w_result) W_Ufunc.typedef = TypeDef("ufunc", __module__ = "numpypy", diff --git a/pypy/module/micronumpy/test/test_subtype.py b/pypy/module/micronumpy/test/test_subtype.py --- a/pypy/module/micronumpy/test/test_subtype.py +++ b/pypy/module/micronumpy/test/test_subtype.py @@ -267,8 +267,24 @@ def __array_prepare__(self, arr, context): self.called_prepare = True return array(arr).view(type=with_prepare) - a = array(1).view(type=with_prepare) - x = add(a, a) + class with_prepare_fail(ndarray): + called_prepare = False + def __array_prepare__(self, arr, context): + self.called_prepare = True + return array(arr[0]).view(type=with_prepare) + a = array(1) + b = array(1).view(type=with_prepare) + x = add(a, a, out=b) assert x == 2 assert type(x) == with_prepare - assert a.called_prepare + assert x.called_prepare + b.called_prepare = False + a = ones((3, 2)).view(type=with_prepare) + b = ones((3, 2)) + c = ones((3, 2)).view(type=with_prepare_fail) + x = add(a, b, out=a) + assert (x == 2).all() + assert type(x) == with_prepare + assert x.called_prepare + raises(TypeError, add, a, b, out=c) + From noreply at buildbot.pypy.org Sat Sep 21 10:20:27 2013 From: noreply at buildbot.pypy.org (arigo) Date: Sat, 21 Sep 2013 10:20:27 +0200 (CEST) Subject: [pypy-commit] pypy default: Write some tests directly for guard_not_forced_2. Message-ID: <20130921082027.A0C3F1C0209@cobra.cs.uni-duesseldorf.de> Author: Armin Rigo Branch: Changeset: r67031:0da86701160d Date: 2013-09-18 08:25 +0200 http://bitbucket.org/pypy/pypy/changeset/0da86701160d/ Log: Write some tests directly for guard_not_forced_2. diff --git a/rpython/jit/backend/test/runner_test.py b/rpython/jit/backend/test/runner_test.py --- a/rpython/jit/backend/test/runner_test.py +++ b/rpython/jit/backend/test/runner_test.py @@ -2441,6 +2441,32 @@ assert values == [1, 10] assert self.cpu.get_savedata_ref(deadframe) == random_gcref + def test_guard_not_forced_2(self): + cpu = self.cpu + i0 = BoxInt() + i1 = BoxInt() + tok = BoxPtr() + faildescr = BasicFailDescr(1) + ops = [ + ResOperation(rop.INT_ADD, [i0, ConstInt(10)], i1), + ResOperation(rop.FORCE_TOKEN, [], tok), + ResOperation(rop.GUARD_NOT_FORCED_2, [], None, descr=faildescr), + ResOperation(rop.FINISH, [tok], None, descr=BasicFinalDescr(0)) + ] + ops[-2].setfailargs([i1]) + looptoken = JitCellToken() + self.cpu.compile_loop([i0], ops, looptoken) + deadframe = self.cpu.execute_token(looptoken, 20) + fail = self.cpu.get_latest_descr(deadframe) + assert fail.identifier == 0 + frame = self.cpu.get_ref_value(deadframe, 0) + # actually, we should get the same pointer in 'frame' and 'deadframe' + # but it is not the case on LLGraph + if not getattr(self.cpu, 'is_llgraph', False): + assert frame == deadframe + deadframe2 = self.cpu.force(frame) + assert self.cpu.get_int_value(deadframe2, 0) == 30 + def test_call_to_c_function(self): from rpython.rlib.libffi import CDLL, types, ArgChain, FUNCFLAG_CDECL from rpython.rtyper.lltypesystem.ll2ctypes import libc_name 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 @@ -651,10 +651,10 @@ _list_all_operations(result, self.operations, omit_finish) return result - def summary(self, adding_insns={}): # for debugging + def summary(self, adding_insns={}, omit_finish=True): # for debugging "NOT_RPYTHON" insns = adding_insns.copy() - for op in self._all_operations(omit_finish=True): + for op in self._all_operations(omit_finish=omit_finish): opname = op.getopname() insns[opname] = insns.get(opname, 0) + 1 return insns @@ -895,10 +895,10 @@ "found %d %r, expected %d" % (found, insn, expected_count)) return insns - def check_resops(self, expected=None, **check): + def check_resops(self, expected=None, omit_finish=True, **check): insns = {} for loop in self.get_all_loops(): - insns = loop.summary(adding_insns=insns) + insns = loop.summary(adding_insns=insns, omit_finish=omit_finish) return self._check_insns(insns, expected, check) def _check_insns(self, insns, expected, check): 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 @@ -153,6 +153,33 @@ assert res == 10180 self.check_resops(setfield_gc=0, getfield_gc=2) + def test_synchronize_in_return_2(self): + myjitdriver = JitDriver(greens = [], reds = ['n', 'xy'], + virtualizables = ['xy']) + class Foo(object): + pass + def g(xy, n): + myjitdriver.jit_merge_point(xy=xy, n=n) + promote_virtualizable(xy, 'inst_x') + xy.inst_x += 1 + return Foo() + def f(n): + xy = self.setup() + promote_virtualizable(xy, 'inst_x') + xy.inst_x = 10000 + m = 10 + foo = None + while m > 0: + foo = g(xy, n) + m -= 1 + assert foo is not None + promote_virtualizable(xy, 'inst_x') + return xy.inst_x + res = self.meta_interp(f, [18]) + assert res == 10010 + self.check_resops(omit_finish=False, + guard_not_forced_2=1, finish=1) + def test_virtualizable_and_greens(self): myjitdriver = JitDriver(greens = ['m'], reds = ['n', 'xy'], virtualizables = ['xy']) From noreply at buildbot.pypy.org Sat Sep 21 10:20:29 2013 From: noreply at buildbot.pypy.org (arigo) Date: Sat, 21 Sep 2013 10:20:29 +0200 (CEST) Subject: [pypy-commit] pypy default: merge heads Message-ID: <20130921082029.4C2CF1C1007@cobra.cs.uni-duesseldorf.de> Author: Armin Rigo Branch: Changeset: r67032:635bc4fa02ea Date: 2013-09-21 10:19 +0200 http://bitbucket.org/pypy/pypy/changeset/635bc4fa02ea/ Log: merge heads diff --git a/pypy/doc/faq.rst b/pypy/doc/faq.rst --- a/pypy/doc/faq.rst +++ b/pypy/doc/faq.rst @@ -356,7 +356,7 @@ attempt to point newcomers at existing alternatives, which are more mainstream and where they will get help from many people.* - *If anybody seriously wants to promote RPython anyway, he is welcome + *If anybody seriously wants to promote RPython anyway, they are welcome to: we won't actively resist such a plan. There are a lot of things that could be done to make RPython a better Java-ish language for example, starting with supporting non-GIL-based multithreading, but we @@ -396,8 +396,8 @@ patch the generated machine code. So the position of the core PyPy developers is that if anyone wants to -make an N+1'th attempt with LLVM, he is welcome, and he will receive a -bit of help on the IRC channel, but he is left with the burden of proof +make an N+1'th attempt with LLVM, they are welcome, and will be happy to +provide help in the IRC channel, but they are left with the burden of proof that it works. ---------------------- 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 @@ -96,7 +96,7 @@ raise OperationError(space.w_ValueError, space.wrap("index out of range for array")) idx_iter = idx.create_iter() - size = loop.count_all_true_iter(idx_iter, self.get_shape(), idx.get_dtype()) + size = loop.count_all_true_iter(idx_iter, idx.get_shape(), idx.get_dtype()) if size > val.get_size() and val.get_size() > 1: raise OperationError(space.w_ValueError, space.wrap("NumPy boolean array indexing assignment " "cannot assign %d input values to " 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 @@ -374,9 +374,12 @@ def setitem_filter(arr, index, value, size): arr_iter = arr.create_iter() - index_iter = index.create_iter(arr.get_shape()) + 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() value_iter = value.create_iter([size]) - shapelen = len(arr.get_shape()) index_dtype = index.get_dtype() arr_dtype = arr.get_dtype() while not index_iter.done(): 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 @@ -1668,6 +1668,16 @@ return extdef([int], int, llimpl=nice_llimpl, export_name="ll_os.ll_os_nice") + @registering_if(os, 'ctermid') + def register_os_ctermid(self): + os_ctermid = self.llexternal('ctermid', [rffi.CCHARP], rffi.CCHARP) + + def ctermid_llimpl(): + return rffi.charp2str(os_ctermid(lltype.nullptr(rffi.CCHARP.TO))) + + return extdef([], str, llimpl=ctermid_llimpl, + export_name="ll_os.ll_os_ctermid") + # --------------------------- os.stat & variants --------------------------- @registering(os.fstat) From noreply at buildbot.pypy.org Sat Sep 21 10:28:58 2013 From: noreply at buildbot.pypy.org (arigo) Date: Sat, 21 Sep 2013 10:28:58 +0200 (CEST) Subject: [pypy-commit] pypy default: Fix when running on top of PyPy. Message-ID: <20130921082858.0B6C51C3409@cobra.cs.uni-duesseldorf.de> Author: Armin Rigo Branch: Changeset: r67033:1804ac147aa8 Date: 2013-09-21 10:28 +0200 http://bitbucket.org/pypy/pypy/changeset/1804ac147aa8/ Log: Fix when running on top of PyPy. diff --git a/rpython/rlib/parsing/makepackrat.py b/rpython/rlib/parsing/makepackrat.py --- a/rpython/rlib/parsing/makepackrat.py +++ b/rpython/rlib/parsing/makepackrat.py @@ -668,7 +668,7 @@ value = new.function(value.func_code, frame.f_globals) if not hasattr(result, key) and key not in forbidden: setattr(result, key, value) - if result.__init__ is object.__init__: + if result.__init__ == object.__init__: result.__init__ = pcls.__dict__['__init__'] result.init_parser = pcls.__dict__['__init__'] result._code = visitor.get_code() From noreply at buildbot.pypy.org Sat Sep 21 10:30:07 2013 From: noreply at buildbot.pypy.org (arigo) Date: Sat, 21 Sep 2013 10:30:07 +0200 (CEST) Subject: [pypy-commit] lang-scheme default: Upgrade this repo to the current pypy Message-ID: <20130921083007.46CC81C3409@cobra.cs.uni-duesseldorf.de> Author: Armin Rigo Branch: Changeset: r44:3bd6b134d3b4 Date: 2013-09-21 10:29 +0200 http://bitbucket.org/pypy/lang-scheme/changeset/3bd6b134d3b4/ Log: Upgrade this repo to the current pypy diff --git a/scheme/interactive.py b/scheme/interactive.py --- a/scheme/interactive.py +++ b/scheme/interactive.py @@ -6,7 +6,7 @@ ContinuationReturn from scheme.execution import ExecutionContext from scheme.ssparser import parse -from pypy.rlib.parsing.makepackrat import BacktrackException +from rpython.rlib.parsing.makepackrat import BacktrackException import os, sys def check_parens(s): diff --git a/scheme/object.py b/scheme/object.py --- a/scheme/object.py +++ b/scheme/object.py @@ -36,7 +36,7 @@ __slots__ = [] def to_string(self): - return '' + return '<%r>' % (self,) def to_repr(self): return "#" diff --git a/scheme/ssparser.py b/scheme/ssparser.py --- a/scheme/ssparser.py +++ b/scheme/ssparser.py @@ -1,5 +1,5 @@ -from pypy.rlib.parsing.pypackrat import PackratParser -from pypy.rlib.parsing.makepackrat import BacktrackException, Status +from rpython.rlib.parsing.pypackrat import PackratParser +from rpython.rlib.parsing.makepackrat import BacktrackException, Status from scheme.object import W_Pair, W_Integer, W_String, symbol, \ w_nil, W_Boolean, W_Real, \ w_ellipsis, W_Character, SchemeSyntaxError, W_Vector diff --git a/scheme/targetscheme.py b/scheme/targetscheme.py --- a/scheme/targetscheme.py +++ b/scheme/targetscheme.py @@ -2,10 +2,9 @@ A simple standalone target for the scheme interpreter. """ -import autopath import sys -from pypy.rlib.streamio import open_file_as_stream -from pypy.rlib.parsing.makepackrat import BacktrackException +from rpython.rlib.streamio import open_file_as_stream +from rpython.rlib.parsing.makepackrat import BacktrackException from scheme.ssparser import parse from scheme.object import SchemeQuit, ContinuationReturn from scheme.execution import ExecutionContext @@ -29,6 +28,7 @@ ctx = ExecutionContext() try: for sexpr in t: + print sexpr.to_string() # for debugging try: w_retval = sexpr.eval(ctx) print w_retval.to_string() diff --git a/scheme/test/test_parser.py b/scheme/test/test_parser.py --- a/scheme/test/test_parser.py +++ b/scheme/test/test_parser.py @@ -3,7 +3,7 @@ from scheme.object import W_Boolean, W_Real, W_Integer, W_String from scheme.object import W_Pair, W_Nil, W_Symbol, W_Character, W_Vector from scheme.object import SchemeSyntaxError -from pypy.rlib.parsing.makepackrat import BacktrackException +from rpython.rlib.parsing.makepackrat import BacktrackException def parse_sexpr(expr): return parse(expr)[0] From noreply at buildbot.pypy.org Sat Sep 21 14:25:13 2013 From: noreply at buildbot.pypy.org (arigo) Date: Sat, 21 Sep 2013 14:25:13 +0200 (CEST) Subject: [pypy-commit] pypy default: Skip this test that has always been failing. Please fix me. Message-ID: <20130921122513.6A04B1C1154@cobra.cs.uni-duesseldorf.de> Author: Armin Rigo Branch: Changeset: r67034:02561547a035 Date: 2013-09-21 14:24 +0200 http://bitbucket.org/pypy/pypy/changeset/02561547a035/ Log: Skip this test that has always been failing. Please fix me. 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 @@ -1,3 +1,4 @@ +import py from pypy.module.pypyjit.test_pypy_c.test_00_model import BaseTestPyPyC @@ -50,6 +51,7 @@ """) def test_lock_acquire_release(self): + py.test.skip("test too precise, please fix me") def main(n): import threading lock = threading.Lock() From noreply at buildbot.pypy.org Sat Sep 21 14:30:37 2013 From: noreply at buildbot.pypy.org (arigo) Date: Sat, 21 Sep 2013 14:30:37 +0200 (CEST) Subject: [pypy-commit] pypy default: XXX fix me or mark definitely skipped Message-ID: <20130921123037.B807A1C1154@cobra.cs.uni-duesseldorf.de> Author: Armin Rigo Branch: Changeset: r67035:135e4b54c03e Date: 2013-09-21 14:27 +0200 http://bitbucket.org/pypy/pypy/changeset/135e4b54c03e/ Log: XXX fix me or mark definitely skipped diff --git a/pypy/module/_pypyjson/test/test__pypyjson.py b/pypy/module/_pypyjson/test/test__pypyjson.py --- a/pypy/module/_pypyjson/test/test__pypyjson.py +++ b/pypy/module/_pypyjson/test/test__pypyjson.py @@ -1,5 +1,5 @@ # -*- encoding: utf-8 -*- -import py +import py, sys from pypy.module._pypyjson.interp_decoder import JSONDecoder def test_skip_whitespace(): @@ -16,6 +16,9 @@ class AppTest(object): spaceconfig = {"objspace.usemodules._pypyjson": True} + def setup_class(cls): + cls.w_run_on_16bit = cls.space.wrap(sys.maxunicode == 65535) + def test_raise_on_unicode(self): import _pypyjson raises(TypeError, _pypyjson.loads, u"42") @@ -178,11 +181,11 @@ raises(ValueError, "_pypyjson.loads('[1: 2]')") raises(ValueError, "_pypyjson.loads('[1, 2')") raises(ValueError, """_pypyjson.loads('["extra comma",]')""") - + def test_unicode_surrogate_pair(self): + if self.run_on_16bit: + skip("XXX fix me or mark definitely skipped") import _pypyjson expected = u'z\U0001d120x' res = _pypyjson.loads('"z\\ud834\\udd20x"') assert res == expected - - From noreply at buildbot.pypy.org Sat Sep 21 14:30:39 2013 From: noreply at buildbot.pypy.org (arigo) Date: Sat, 21 Sep 2013 14:30:39 +0200 (CEST) Subject: [pypy-commit] pypy default: Fix the test, failing if sys.unicode==65535. Message-ID: <20130921123039.6B5611C1154@cobra.cs.uni-duesseldorf.de> Author: Armin Rigo Branch: Changeset: r67036:2e490cdd9f25 Date: 2013-09-21 14:29 +0200 http://bitbucket.org/pypy/pypy/changeset/2e490cdd9f25/ Log: Fix the test, failing if sys.unicode==65535. diff --git a/rpython/rlib/test/test_runicode.py b/rpython/rlib/test/test_runicode.py --- a/rpython/rlib/test/test_runicode.py +++ b/rpython/rlib/test/test_runicode.py @@ -246,7 +246,8 @@ assert decode('+3AE-', 5, None) == (u'\uDC01', 5) assert decode('+3AE-x', 6, None) == (u'\uDC01x', 6) - assert encode(u'\uD801\U000abcde', 2, None) == '+2AHab9ze-' + u = u'\uD801\U000abcde' + assert encode(u, len(u), None) == '+2AHab9ze-' assert decode('+2AHab9ze-', 10, None) == (u'\uD801\U000abcde', 10) From noreply at buildbot.pypy.org Sat Sep 21 14:40:03 2013 From: noreply at buildbot.pypy.org (arigo) Date: Sat, 21 Sep 2013 14:40:03 +0200 (CEST) Subject: [pypy-commit] pypy default: Fix to (hopefully) support more cases of 16/32-bit-sized unicode chars Message-ID: <20130921124003.7F0D71C013B@cobra.cs.uni-duesseldorf.de> Author: Armin Rigo Branch: Changeset: r67037:162d46b91e96 Date: 2013-09-21 14:39 +0200 http://bitbucket.org/pypy/pypy/changeset/162d46b91e96/ Log: Fix to (hopefully) support more cases of 16/32-bit-sized unicode chars diff --git a/rpython/rlib/unicodedata/test/test_ucd.py b/rpython/rlib/unicodedata/test/test_ucd.py --- a/rpython/rlib/unicodedata/test/test_ucd.py +++ b/rpython/rlib/unicodedata/test/test_ucd.py @@ -1,6 +1,7 @@ -from rpython.rlib.runicode import code_to_unichr +from rpython.rlib.runicode import code_to_unichr, MAXUNICODE from rpython.rlib.unicodedata import unicodedb_5_2_0 from rpython.rtyper.test.tool import BaseRtypingTest +from rpython.translator.c.test.test_genc import compile class TestTranslated(BaseRtypingTest): @@ -15,8 +16,13 @@ print hex(res) assert res == f(1) - def test_code_to_unichr(self): - def f(c): - return code_to_unichr(c) + u'' - res = self.ll_to_unicode(self.interpret(f, [0x10346])) - assert res == u'\U00010346' + +def test_code_to_unichr(): + def f(c): + return ord(code_to_unichr(c)[0]) + f1 = compile(f, [int]) + got = f1(0x12346) + if MAXUNICODE == 65535: + assert got == 0xd808 # first char of a pair + else: + assert got == 0x12346 From noreply at buildbot.pypy.org Sat Sep 21 23:38:17 2013 From: noreply at buildbot.pypy.org (mattip) Date: Sat, 21 Sep 2013 23:38:17 +0200 (CEST) Subject: [pypy-commit] pypy numpypy-array_prepare_-array_wrap: add branch for __array_preprare__, __array_wrap__ Message-ID: <20130921213817.C7CED1C1154@cobra.cs.uni-duesseldorf.de> Author: Matti Picus Branch: numpypy-array_prepare_-array_wrap Changeset: r67038:b0315f391eb5 Date: 2013-09-22 00:10 +0300 http://bitbucket.org/pypy/pypy/changeset/b0315f391eb5/ Log: add branch for __array_preprare__, __array_wrap__ From noreply at buildbot.pypy.org Sat Sep 21 23:38:19 2013 From: noreply at buildbot.pypy.org (mattip) Date: Sat, 21 Sep 2013 23:38:19 +0200 (CEST) Subject: [pypy-commit] pypy numpypy-array_prepare_-array_wrap: add test for ufunc1 and reduce, but numpy does not actually call __array_prepare__. numpy bug? Message-ID: <20130921213819.05A221C1190@cobra.cs.uni-duesseldorf.de> Author: Matti Picus Branch: numpypy-array_prepare_-array_wrap Changeset: r67039:8e72bf2e4160 Date: 2013-09-20 13:39 +0300 http://bitbucket.org/pypy/pypy/changeset/8e72bf2e4160/ Log: add test for ufunc1 and reduce, but numpy does not actually call __array_prepare__. numpy bug? diff --git a/pypy/module/micronumpy/test/test_subtype.py b/pypy/module/micronumpy/test/test_subtype.py --- a/pypy/module/micronumpy/test/test_subtype.py +++ b/pypy/module/micronumpy/test/test_subtype.py @@ -260,7 +260,7 @@ assert type(x) == ndarray assert a.called_wrap - def test___array_prepare__(self): + def test___array_prepare__1(self): from numpypy import ndarray, array, add, ones class with_prepare(ndarray): called_prepare = False @@ -288,3 +288,21 @@ assert x.called_prepare raises(TypeError, add, a, b, out=c) + def test___array_prepare__2(self): + from numpypy import ndarray, array, sum, ones, add + class with_prepare(ndarray): + def __array_prepare__(self, arr, context): + x = array(arr).view(type=with_prepare) + x.called_prepare = True + xxx + print 'called_prepare',arr + return x + a = ones(2).view(type=with_prepare) + b = ones((3, 2)) + x = sum(a, axis=0) + assert type(x) == with_prepare + # reduce functions do not call prepare? + assert not getattr(x, 'called_prepare',False) + x = add.reduce(a) + assert type(x) == with_prepare + assert not getattr(x, 'called_prepare',False) From noreply at buildbot.pypy.org Sat Sep 21 23:38:20 2013 From: noreply at buildbot.pypy.org (mattip) Date: Sat, 21 Sep 2013 23:38:20 +0200 (CEST) Subject: [pypy-commit] pypy numpypy-array_prepare_-array_wrap: allow Box results to percolate through, start to fix compile.py Message-ID: <20130921213820.3ABE01C1154@cobra.cs.uni-duesseldorf.de> Author: Matti Picus Branch: numpypy-array_prepare_-array_wrap Changeset: r67040:e69c4253c9d7 Date: 2013-09-20 16:28 +0300 http://bitbucket.org/pypy/pypy/changeset/e69c4253c9d7/ Log: allow Box results to percolate through, start to fix compile.py diff --git a/pypy/module/micronumpy/compile.py b/pypy/module/micronumpy/compile.py --- a/pypy/module/micronumpy/compile.py +++ b/pypy/module/micronumpy/compile.py @@ -222,6 +222,10 @@ return None #return getattr(w_obj, 'descr_' + s)(self, *args) + def get_and_call_function(self, w_descr, w_obj, *args_w): + w_impl = self.getattr(w_descr, w_obj) + return self.call_method(w_obj, w_impl, args_w) + @specialize.arg(1) def interp_w(self, tp, what): assert isinstance(what, tp) 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 @@ -439,7 +439,7 @@ def descr___array_prepare__(self, space, w_array, w_context): # stub implementation of __array_prepare__() - if isinstance(w_array, W_NDimArray): + if isinstance(w_array, (W_NDimArray, interp_boxes.Box)): return w_array else: raise OperationError(space.w_TypeError, 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 @@ -234,6 +234,37 @@ return out return res + def call_prepare(self, space, w_out, w_obj, w_result): + if isinstance(w_out, W_NDimArray): + w_array = space.lookup(w_out, "__array_prepare__") + w_caller = w_out + else: + w_array = space.lookup(w_obj, "__array_prepare__") + w_caller = w_obj + if w_array: + w_retVal = space.get_and_call_function(w_array, w_caller, w_result, None) + if not isinstance(w_retVal, (W_NDimArray, interp_boxes.Box)): + raise OperationError(space.w_ValueError, + space.wrap( "__array_prepare__ must return an " + "ndarray or subclass thereof")) + if isinstance(w_result, interp_boxes.Box) or \ + w_result.is_scalar(): + if not isinstance(w_retVal, interp_boxes.Box) and not w_retVal.is_scalar(): + raise OperationError(space.w_TypeError, + space.wrap( "__array_prepare__ must return an " + "ndarray or subclass thereof which is " + "otherwise identical to its input")) + elif w_result.get_shape() != w_retVal.get_shape() or \ + w_result.implementation.get_strides() != \ + w_retVal.implementation.get_strides(): + raise OperationError(space.w_TypeError, + space.wrap( "__array_prepare__ must return an " + "ndarray or subclass thereof which is " + "otherwise identical to its input")) + return w_retVal + return w_result + + class W_Ufunc1(W_Ufunc): argcount = 1 @@ -319,22 +350,6 @@ else: self.done_func = None - def call_prepare(self, space, w_out, w_obj, w_result): - if isinstance(w_out, W_NDimArray): - w_array = space.lookup(w_out, "__array_prepare__") - w_caller = w_out - else: - w_array = space.lookup(w_obj, "__array_prepare__") - w_caller = w_obj - if w_array: - w_result = space.get_and_call_function(w_array, w_caller, w_result, None) - if not isinstance(w_result, W_NDimArray): - raise OperationError(space.w_ValueError, - space.wrap("object __array_prepare__ method not" - " producing an array")) - return w_result - - @jit.unroll_safe def call(self, space, args_w): if len(args_w) > 2: @@ -387,6 +402,7 @@ out.set_scalar_value(arr) else: out.fill(arr) + arr = out return self.call_prepare(space, out, w_lhs, arr) new_shape = shape_agreement(space, w_lhs.get_shape(), w_rhs) new_shape = shape_agreement(space, new_shape, out, broadcast_down=False) From noreply at buildbot.pypy.org Sat Sep 21 23:38:21 2013 From: noreply at buildbot.pypy.org (mattip) Date: Sat, 21 Sep 2013 23:38:21 +0200 (CEST) Subject: [pypy-commit] pypy numpypy-array_prepare_-array_wrap: add 1 arg ufunc tests Message-ID: <20130921213821.6566F1C1154@cobra.cs.uni-duesseldorf.de> Author: Matti Picus Branch: numpypy-array_prepare_-array_wrap Changeset: r67041:4c78008e85f4 Date: 2013-09-20 17:00 +0300 http://bitbucket.org/pypy/pypy/changeset/4c78008e85f4/ Log: add 1 arg ufunc tests diff --git a/pypy/module/micronumpy/test/test_subtype.py b/pypy/module/micronumpy/test/test_subtype.py --- a/pypy/module/micronumpy/test/test_subtype.py +++ b/pypy/module/micronumpy/test/test_subtype.py @@ -260,17 +260,16 @@ assert type(x) == ndarray assert a.called_wrap - def test___array_prepare__1(self): + def test___array_prepare__2arg(self): from numpypy import ndarray, array, add, ones class with_prepare(ndarray): - called_prepare = False def __array_prepare__(self, arr, context): - self.called_prepare = True - return array(arr).view(type=with_prepare) + retVal = array(arr).view(type=with_prepare) + retVal.called_prepare = True + return retVal class with_prepare_fail(ndarray): called_prepare = False def __array_prepare__(self, arr, context): - self.called_prepare = True return array(arr[0]).view(type=with_prepare) a = array(1) b = array(1).view(type=with_prepare) @@ -288,17 +287,42 @@ assert x.called_prepare raises(TypeError, add, a, b, out=c) - def test___array_prepare__2(self): + def test___array_prepare__1arg(self): + from numpypy import ndarray, array, log, ones + class with_prepare(ndarray): + def __array_prepare__(self, arr, context): + retVal = array(arr).view(type=with_prepare) + retVal.called_prepare = True + return retVal + class with_prepare_fail(ndarray): + def __array_prepare__(self, arr, context): + return array(arr[0]).view(type=with_prepare) + a = array(1) + b = array(1).view(type=with_prepare) + x = log(a, out=b) + assert x == 0 + assert type(x) == with_prepare + assert x.called_prepare + x.called_prepare = False + a = ones((3, 2)).view(type=with_prepare) + b = ones((3, 2)) + c = ones((3, 2)).view(type=with_prepare_fail) + x = log(a) + assert (x == 0).all() + assert type(x) == with_prepare + assert x.called_prepare + raises(TypeError, log, a, out=c) + + + def test___array_prepare__nocall(self): from numpypy import ndarray, array, sum, ones, add class with_prepare(ndarray): def __array_prepare__(self, arr, context): x = array(arr).view(type=with_prepare) x.called_prepare = True - xxx print 'called_prepare',arr return x a = ones(2).view(type=with_prepare) - b = ones((3, 2)) x = sum(a, axis=0) assert type(x) == with_prepare # reduce functions do not call prepare? From noreply at buildbot.pypy.org Sat Sep 21 23:38:22 2013 From: noreply at buildbot.pypy.org (mattip) Date: Sat, 21 Sep 2013 23:38:22 +0200 (CEST) Subject: [pypy-commit] pypy numpypy-array_prepare_-array_wrap: update test, fix implementation of reduce Message-ID: <20130921213822.99BF71C1154@cobra.cs.uni-duesseldorf.de> Author: Matti Picus Branch: numpypy-array_prepare_-array_wrap Changeset: r67042:5c0ec116cb8b Date: 2013-09-21 22:37 +0300 http://bitbucket.org/pypy/pypy/changeset/5c0ec116cb8b/ Log: update test, fix implementation of reduce 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 @@ -232,6 +232,9 @@ if out: out.set_scalar_value(res) return out + if space.type(obj) != W_NDimArray: + #If obj is a subtype of W_NDimArray, return a empty-shape instance + return W_NDimArray.from_shape(space, [], dtype, w_instance=obj) return res def call_prepare(self, space, w_out, w_obj, w_result): diff --git a/pypy/module/micronumpy/test/test_subtype.py b/pypy/module/micronumpy/test/test_subtype.py --- a/pypy/module/micronumpy/test/test_subtype.py +++ b/pypy/module/micronumpy/test/test_subtype.py @@ -314,7 +314,7 @@ raises(TypeError, log, a, out=c) - def test___array_prepare__nocall(self): + def test___array_prepare__reduce(self): from numpypy import ndarray, array, sum, ones, add class with_prepare(ndarray): def __array_prepare__(self, arr, context): @@ -323,10 +323,15 @@ print 'called_prepare',arr return x a = ones(2).view(type=with_prepare) - x = sum(a, axis=0) + x = sum(a) assert type(x) == with_prepare - # reduce functions do not call prepare? + assert x.shape == () + # reduce functions do not call prepare, is this a numpy 'feature'? assert not getattr(x, 'called_prepare',False) x = add.reduce(a) assert type(x) == with_prepare assert not getattr(x, 'called_prepare',False) + a = ones((2,3)).view(type=with_prepare) + x = sum(a, axis=0) + assert type(x) == with_prepare + assert not getattr(x, 'called_prepare',False) From noreply at buildbot.pypy.org Sat Sep 21 23:38:24 2013 From: noreply at buildbot.pypy.org (mattip) Date: Sat, 21 Sep 2013 23:38:24 +0200 (CEST) Subject: [pypy-commit] pypy numpypy-array_prepare_-array_wrap: typo, fix if clause, actually set return value Message-ID: <20130921213824.3DB511C1154@cobra.cs.uni-duesseldorf.de> Author: Matti Picus Branch: numpypy-array_prepare_-array_wrap Changeset: r67043:d3b4a2771960 Date: 2013-09-21 23:11 +0300 http://bitbucket.org/pypy/pypy/changeset/d3b4a2771960/ Log: typo, fix if clause, actually set return value 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 @@ -852,7 +852,7 @@ # ----------------------- reduce ------------------------------- def _reduce_ufunc_impl(ufunc_name, promote_to_largest=False, - cumultative=False): + cumulative=False): def impl(self, space, w_axis=None, w_out=None, w_dtype=None): if space.is_none(w_out): out = None @@ -863,9 +863,9 @@ out = w_out return getattr(interp_ufuncs.get(space), ufunc_name).reduce( space, self, True, promote_to_largest, w_axis, - False, out, w_dtype, cumultative=cumultative) + False, out, w_dtype, cumulative=cumulative) return func_with_new_name(impl, "reduce_%s_impl_%d_%d" % (ufunc_name, - promote_to_largest, cumultative)) + promote_to_largest, cumulative)) descr_sum = _reduce_ufunc_impl("add") descr_sum_promote = _reduce_ufunc_impl("add", True) @@ -875,8 +875,8 @@ descr_all = _reduce_ufunc_impl('logical_and') descr_any = _reduce_ufunc_impl('logical_or') - descr_cumsum = _reduce_ufunc_impl('add', cumultative=True) - descr_cumprod = _reduce_ufunc_impl('multiply', cumultative=True) + descr_cumsum = _reduce_ufunc_impl('add', cumulative=True) + descr_cumprod = _reduce_ufunc_impl('multiply', cumulative=True) def descr_mean(self, space, w_axis=None, w_out=None): if space.is_none(w_axis): 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 @@ -144,7 +144,7 @@ w_dtype) def reduce(self, space, w_obj, multidim, promote_to_largest, w_axis, - keepdims=False, out=None, dtype=None, cumultative=False): + keepdims=False, out=None, dtype=None, cumulative=False): if self.argcount != 2: raise OperationError(space.w_ValueError, space.wrap("reduce only " "supported for binary functions")) @@ -176,7 +176,7 @@ "%s.reduce without identity", self.name) if shapelen > 1 and axis < shapelen: temp = None - if cumultative: + if cumulative: shape = obj_shape[:] temp_shape = obj_shape[:axis] + obj_shape[axis + 1:] if out: @@ -210,8 +210,8 @@ else: out = W_NDimArray.from_shape(space, shape, dtype, w_instance=obj) return loop.do_axis_reduce(shape, self.func, obj, dtype, axis, out, - self.identity, cumultative, temp) - if cumultative: + self.identity, cumulative, temp) + if cumulative: if out: if out.get_shape() != [obj.get_size()]: raise OperationError(space.w_ValueError, space.wrap( @@ -232,9 +232,11 @@ if out: out.set_scalar_value(res) return out - if space.type(obj) != W_NDimArray: + if not type(obj) == W_NDimArray: #If obj is a subtype of W_NDimArray, return a empty-shape instance - return W_NDimArray.from_shape(space, [], dtype, w_instance=obj) + out = W_NDimArray.from_shape(space, [], dtype, w_instance=obj) + out.set_scalar_value(res) + return out return res def call_prepare(self, space, w_out, w_obj, w_result): diff --git a/pypy/module/micronumpy/iter.py b/pypy/module/micronumpy/iter.py --- a/pypy/module/micronumpy/iter.py +++ b/pypy/module/micronumpy/iter.py @@ -275,11 +275,11 @@ return self.indexes[d] class AxisIterator(base.BaseArrayIterator): - def __init__(self, array, shape, dim, cumultative): + def __init__(self, array, shape, dim, cumulative): self.shape = shape strides = array.get_strides() backstrides = array.get_backstrides() - if cumultative: + if cumulative: self.strides = strides self.backstrides = backstrides elif len(shape) == len(strides): 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 @@ -218,10 +218,10 @@ 'func', 'dtype'], reds='auto') -def do_axis_reduce(shape, func, arr, dtype, axis, out, identity, cumultative, +def do_axis_reduce(shape, func, arr, dtype, axis, out, identity, cumulative, temp): - out_iter = out.create_axis_iter(arr.get_shape(), axis, cumultative) - if cumultative: + out_iter = out.create_axis_iter(arr.get_shape(), axis, cumulative) + if cumulative: temp_iter = temp.create_axis_iter(arr.get_shape(), axis, False) else: temp_iter = out_iter # hack @@ -240,7 +240,7 @@ cur = temp_iter.getitem() w_val = func(dtype, cur, w_val) out_iter.setitem(w_val) - if cumultative: + if cumulative: temp_iter.setitem(w_val) temp_iter.next() arr_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 @@ -1342,7 +1342,8 @@ a = array(range(5)) assert a.all() == False a[0] = 3.0 - assert a.all() == True + b = a.all() + assert b == True b = array([]) assert b.all() == True @@ -2138,7 +2139,8 @@ b = a[1:, 1::2] c = b + b assert c.sum() == (6 + 8 + 10 + 12) * 2 - assert isinstance(c.sum(dtype='f8'), float) + d = c.sum(dtype='f8') + assert isinstance(d, float) def test_transpose(self): from numpypy import array From noreply at buildbot.pypy.org Sat Sep 21 23:38:26 2013 From: noreply at buildbot.pypy.org (mattip) Date: Sat, 21 Sep 2013 23:38:26 +0200 (CEST) Subject: [pypy-commit] pypy numpypy-array_prepare_-array_wrap: implement for W_Ufunc1 Message-ID: <20130921213826.0FAB51C1154@cobra.cs.uni-duesseldorf.de> Author: Matti Picus Branch: numpypy-array_prepare_-array_wrap Changeset: r67044:47a1da6a0385 Date: 2013-09-21 23:51 +0300 http://bitbucket.org/pypy/pypy/changeset/47a1da6a0385/ Log: implement for W_Ufunc1 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 @@ -325,15 +325,17 @@ w_obj.get_scalar_value().convert_to(calc_dtype)) if out is None: return w_val - if out.is_scalar(): - out.set_scalar_value(w_val) - else: - out.fill(res_dtype.coerce(space, w_val)) - return out + if isinstance(out, W_NDimArray): + if out.is_scalar(): + out.set_scalar_value(w_val) + else: + out.fill(res_dtype.coerce(space, w_val)) + return self.call_prepare(space, out, w_obj, w_val) shape = shape_agreement(space, w_obj.get_shape(), out, broadcast_down=False) - return loop.call1(space, shape, self.func, calc_dtype, res_dtype, + w_result = loop.call1(space, shape, self.func, calc_dtype, res_dtype, w_obj, out) + return self.call_prepare(space, out, w_obj, w_result) class W_Ufunc2(W_Ufunc): @@ -408,6 +410,7 @@ else: out.fill(arr) arr = out + # XXX handle array_priority return self.call_prepare(space, out, w_lhs, arr) new_shape = shape_agreement(space, w_lhs.get_shape(), w_rhs) new_shape = shape_agreement(space, new_shape, out, broadcast_down=False) diff --git a/pypy/module/micronumpy/test/test_subtype.py b/pypy/module/micronumpy/test/test_subtype.py --- a/pypy/module/micronumpy/test/test_subtype.py +++ b/pypy/module/micronumpy/test/test_subtype.py @@ -299,8 +299,11 @@ return array(arr[0]).view(type=with_prepare) a = array(1) b = array(1).view(type=with_prepare) + print 'xxxxxxxxxxxxxxxxxxxxxxxxxxxxx' x = log(a, out=b) + print 'aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa' assert x == 0 + print 'xxxxxxxxxxxxxxxxxxxxxxxxxxxxx' assert type(x) == with_prepare assert x.called_prepare x.called_prepare = False From noreply at buildbot.pypy.org Sat Sep 21 23:38:27 2013 From: noreply at buildbot.pypy.org (mattip) Date: Sat, 21 Sep 2013 23:38:27 +0200 (CEST) Subject: [pypy-commit] pypy numpypy-array_prepare_-array_wrap: fix translation Message-ID: <20130921213827.2721D1C1154@cobra.cs.uni-duesseldorf.de> Author: Matti Picus Branch: numpypy-array_prepare_-array_wrap Changeset: r67045:995703e4a6b6 Date: 2013-09-22 00:08 +0300 http://bitbucket.org/pypy/pypy/changeset/995703e4a6b6/ Log: fix translation 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 @@ -439,7 +439,8 @@ def descr___array_prepare__(self, space, w_array, w_context): # stub implementation of __array_prepare__() - if isinstance(w_array, (W_NDimArray, interp_boxes.Box)): + if isinstance(w_array, W_NDimArray) or \ + isinstance(w_array, interp_boxes.Box): return w_array else: raise OperationError(space.w_TypeError, 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 @@ -232,7 +232,7 @@ if out: out.set_scalar_value(res) return out - if not type(obj) == W_NDimArray: + if type(obj) is not W_NDimArray: #If obj is a subtype of W_NDimArray, return a empty-shape instance out = W_NDimArray.from_shape(space, [], dtype, w_instance=obj) out.set_scalar_value(res) @@ -240,6 +240,7 @@ return res def call_prepare(self, space, w_out, w_obj, w_result): + assert isinstance(w_result, W_NDimArray) if isinstance(w_out, W_NDimArray): w_array = space.lookup(w_out, "__array_prepare__") w_caller = w_out @@ -248,7 +249,8 @@ w_caller = w_obj if w_array: w_retVal = space.get_and_call_function(w_array, w_caller, w_result, None) - if not isinstance(w_retVal, (W_NDimArray, interp_boxes.Box)): + if not isinstance(w_retVal, W_NDimArray) and \ + not isinstance(w_retVal, interp_boxes.Box): raise OperationError(space.w_ValueError, space.wrap( "__array_prepare__ must return an " "ndarray or subclass thereof")) From noreply at buildbot.pypy.org Sat Sep 21 23:38:28 2013 From: noreply at buildbot.pypy.org (mattip) Date: Sat, 21 Sep 2013 23:38:28 +0200 (CEST) Subject: [pypy-commit] pypy pypy-pyarray: Backed out changeset: b95fcd12507d - belongs on branch Message-ID: <20130921213828.473351C1154@cobra.cs.uni-duesseldorf.de> Author: Matti Picus Branch: pypy-pyarray Changeset: r67046:c51e676b8312 Date: 2013-09-22 00:17 +0300 http://bitbucket.org/pypy/pypy/changeset/c51e676b8312/ Log: Backed out changeset: b95fcd12507d - belongs on branch 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 @@ -86,7 +86,7 @@ return W_NDimArray(scalar.Scalar(dtype, w_val)) -def convert_to_array(space, w_obj, use_prepare=False): +def convert_to_array(space, w_obj): #XXX: This whole routine should very likely simply be array() from pypy.module.micronumpy.interp_numarray import array from pypy.module.micronumpy import interp_ufuncs @@ -101,7 +101,7 @@ if isinstance(w_result, W_NDimArray): return w_result else: - raise OperationError(space.w_ValueError, + raise OperationError(space.w_ValueError, space.wrap("object __array__ method not producing an array")) elif issequence_w(space, w_obj): # Convert to 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 @@ -437,7 +437,7 @@ # stub implementation of __array__() return self - def descr___array_prepare__(self, space, w_array, w_context): + def descr___array_prepare__(self, space, w_array): # stub implementation of __array_prepare__() if isinstance(w_array, W_NDimArray): return w_array 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 @@ -319,22 +319,6 @@ else: self.done_func = None - def call_prepare(self, space, w_out, w_obj, w_result): - if isinstance(w_out, W_NDimArray): - w_array = space.lookup(w_out, "__array_prepare__") - w_caller = w_out - else: - w_array = space.lookup(w_obj, "__array_prepare__") - w_caller = w_obj - if w_array: - w_result = space.get_and_call_function(w_array, w_caller, w_result, None) - if not isinstance(w_result, W_NDimArray): - raise OperationError(space.w_ValueError, - space.wrap("object __array_prepare__ method not" - " producing an array")) - return w_result - - @jit.unroll_safe def call(self, space, args_w): if len(args_w) > 2: @@ -367,11 +351,11 @@ "ufunc '%s' not supported for the input types" % self.name)) if space.is_none(w_out): out = None - #elif not isinstance(w_out, W_NDimArray): - # raise OperationError(space.w_TypeError, space.wrap( - # 'output must be an array')) + elif not isinstance(w_out, W_NDimArray): + raise OperationError(space.w_TypeError, space.wrap( + 'output must be an array')) else: - out = convert_to_array(space, w_out) + out = w_out calc_dtype = out.get_dtype() if self.comparison_func: res_dtype = interp_dtype.get_dtype_cache(space).w_booldtype @@ -387,13 +371,14 @@ out.set_scalar_value(arr) else: out.fill(arr) - return self.call_prepare(space, out, w_lhs, arr) + else: + out = arr + return out new_shape = shape_agreement(space, w_lhs.get_shape(), w_rhs) new_shape = shape_agreement(space, new_shape, out, broadcast_down=False) - w_result = loop.call2(space, new_shape, self.func, calc_dtype, + return loop.call2(space, new_shape, self.func, calc_dtype, res_dtype, w_lhs, w_rhs, out) - # XXX handle array_priority - return self.call_prepare(space, out, w_lhs, w_result) + W_Ufunc.typedef = TypeDef("ufunc", __module__ = "numpypy", diff --git a/pypy/module/micronumpy/test/test_subtype.py b/pypy/module/micronumpy/test/test_subtype.py --- a/pypy/module/micronumpy/test/test_subtype.py +++ b/pypy/module/micronumpy/test/test_subtype.py @@ -267,24 +267,8 @@ def __array_prepare__(self, arr, context): self.called_prepare = True return array(arr).view(type=with_prepare) - class with_prepare_fail(ndarray): - called_prepare = False - def __array_prepare__(self, arr, context): - self.called_prepare = True - return array(arr[0]).view(type=with_prepare) - a = array(1) - b = array(1).view(type=with_prepare) - x = add(a, a, out=b) + a = array(1).view(type=with_prepare) + x = add(a, a) assert x == 2 assert type(x) == with_prepare - assert x.called_prepare - b.called_prepare = False - a = ones((3, 2)).view(type=with_prepare) - b = ones((3, 2)) - c = ones((3, 2)).view(type=with_prepare_fail) - x = add(a, b, out=a) - assert (x == 2).all() - assert type(x) == with_prepare - assert x.called_prepare - raises(TypeError, add, a, b, out=c) - + assert a.called_prepare From noreply at buildbot.pypy.org Sat Sep 21 23:38:29 2013 From: noreply at buildbot.pypy.org (mattip) Date: Sat, 21 Sep 2013 23:38:29 +0200 (CEST) Subject: [pypy-commit] pypy pypy-pyarray: move 61c630f73ba3 to branch and remove untested __array_prepare__, __array_wrap__ Message-ID: <20130921213829.66B851C1154@cobra.cs.uni-duesseldorf.de> Author: Matti Picus Branch: pypy-pyarray Changeset: r67047:746c18a936f7 Date: 2013-09-22 00:21 +0300 http://bitbucket.org/pypy/pypy/changeset/746c18a936f7/ Log: move 61c630f73ba3 to branch and remove untested __array_prepare__, __array_wrap__ 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 @@ -437,22 +437,6 @@ # stub implementation of __array__() return self - def descr___array_prepare__(self, space, w_array): - # stub implementation of __array_prepare__() - if isinstance(w_array, W_NDimArray): - return w_array - else: - raise OperationError(space.w_TypeError, - space.wrap("can only be called with ndarray object")) - - def descr___array_wrap__(self, space, w_array): - # stub implementation of __array_wrap__() - if isinstance(w_array, W_NDimArray): - return w_array - else: - raise OperationError(space.w_TypeError, - space.wrap("can only be called with ndarray object")) - def descr_array_iface(self, space): addr = self.implementation.get_storage_as_int(space) # will explode if it can't @@ -1157,8 +1141,6 @@ __array_finalize__ = interp2app(W_NDimArray.descr___array_finalize__), __array__ = interp2app(W_NDimArray.descr___array__), - __array_prepare__ = interp2app(W_NDimArray.descr___array_prepare__), - __array_wrap__ = interp2app(W_NDimArray.descr___array_wrap__), ) @unwrap_spec(ndmin=int, copy=bool, subok=bool) diff --git a/pypy/module/micronumpy/test/test_subtype.py b/pypy/module/micronumpy/test/test_subtype.py --- a/pypy/module/micronumpy/test/test_subtype.py +++ b/pypy/module/micronumpy/test/test_subtype.py @@ -245,30 +245,3 @@ c = array(a, float) assert c.dtype is dtype(float) - def test___array_wrap__(self): - from numpypy import ndarray, add, ones - class with_wrap(object): - called_wrap = False - def __array__(self): - return ones(1) - def __array_wrap__(self, arr, context): - self.called_wrap = True - return arr - a = with_wrap() - x = add(a, a) - assert x == 2 - assert type(x) == ndarray - assert a.called_wrap - - def test___array_prepare__(self): - from numpypy import ndarray, array, add, ones - class with_prepare(ndarray): - called_prepare = False - def __array_prepare__(self, arr, context): - self.called_prepare = True - return array(arr).view(type=with_prepare) - a = array(1).view(type=with_prepare) - x = add(a, a) - assert x == 2 - assert type(x) == with_prepare - assert a.called_prepare From noreply at buildbot.pypy.org Sat Sep 21 23:38:30 2013 From: noreply at buildbot.pypy.org (mattip) Date: Sat, 21 Sep 2013 23:38:30 +0200 (CEST) Subject: [pypy-commit] pypy pypy-pyarray: finish review items for pypy-pyarray branch Message-ID: <20130921213830.96EE01C1154@cobra.cs.uni-duesseldorf.de> Author: Matti Picus Branch: pypy-pyarray Changeset: r67048:74096886f5f4 Date: 2013-09-22 00:22 +0300 http://bitbucket.org/pypy/pypy/changeset/74096886f5f4/ Log: finish review items for pypy-pyarray branch diff --git a/TODO.txt b/TODO.txt deleted file mode 100644 --- a/TODO.txt +++ /dev/null @@ -1,5 +0,0 @@ -TODO list by mattip -=================== - -- test, implement use of __array_prepare__() -- test, implement use of __array_wrap__() From noreply at buildbot.pypy.org Sat Sep 21 23:38:31 2013 From: noreply at buildbot.pypy.org (mattip) Date: Sat, 21 Sep 2013 23:38:31 +0200 (CEST) Subject: [pypy-commit] pypy pypy-pyarray: merge default into branch Message-ID: <20130921213831.E69011C1154@cobra.cs.uni-duesseldorf.de> Author: Matti Picus Branch: pypy-pyarray Changeset: r67049:e8756ac043ff Date: 2013-09-22 00:37 +0300 http://bitbucket.org/pypy/pypy/changeset/e8756ac043ff/ Log: merge default into branch diff --git a/pypy/module/_pypyjson/test/test__pypyjson.py b/pypy/module/_pypyjson/test/test__pypyjson.py --- a/pypy/module/_pypyjson/test/test__pypyjson.py +++ b/pypy/module/_pypyjson/test/test__pypyjson.py @@ -1,5 +1,5 @@ # -*- encoding: utf-8 -*- -import py +import py, sys from pypy.module._pypyjson.interp_decoder import JSONDecoder def test_skip_whitespace(): @@ -16,6 +16,9 @@ class AppTest(object): spaceconfig = {"objspace.usemodules._pypyjson": True} + def setup_class(cls): + cls.w_run_on_16bit = cls.space.wrap(sys.maxunicode == 65535) + def test_raise_on_unicode(self): import _pypyjson raises(TypeError, _pypyjson.loads, u"42") @@ -178,11 +181,11 @@ raises(ValueError, "_pypyjson.loads('[1: 2]')") raises(ValueError, "_pypyjson.loads('[1, 2')") raises(ValueError, """_pypyjson.loads('["extra comma",]')""") - + def test_unicode_surrogate_pair(self): + if self.run_on_16bit: + skip("XXX fix me or mark definitely skipped") import _pypyjson expected = u'z\U0001d120x' res = _pypyjson.loads('"z\\ud834\\udd20x"') assert res == expected - - 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 @@ -1,3 +1,4 @@ +import py from pypy.module.pypyjit.test_pypy_c.test_00_model import BaseTestPyPyC @@ -50,6 +51,7 @@ """) def test_lock_acquire_release(self): + py.test.skip("test too precise, please fix me") def main(n): import threading lock = threading.Lock() 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 @@ -2441,6 +2441,32 @@ assert values == [1, 10] assert self.cpu.get_savedata_ref(deadframe) == random_gcref + def test_guard_not_forced_2(self): + cpu = self.cpu + i0 = BoxInt() + i1 = BoxInt() + tok = BoxPtr() + faildescr = BasicFailDescr(1) + ops = [ + ResOperation(rop.INT_ADD, [i0, ConstInt(10)], i1), + ResOperation(rop.FORCE_TOKEN, [], tok), + ResOperation(rop.GUARD_NOT_FORCED_2, [], None, descr=faildescr), + ResOperation(rop.FINISH, [tok], None, descr=BasicFinalDescr(0)) + ] + ops[-2].setfailargs([i1]) + looptoken = JitCellToken() + self.cpu.compile_loop([i0], ops, looptoken) + deadframe = self.cpu.execute_token(looptoken, 20) + fail = self.cpu.get_latest_descr(deadframe) + assert fail.identifier == 0 + frame = self.cpu.get_ref_value(deadframe, 0) + # actually, we should get the same pointer in 'frame' and 'deadframe' + # but it is not the case on LLGraph + if not getattr(self.cpu, 'is_llgraph', False): + assert frame == deadframe + deadframe2 = self.cpu.force(frame) + assert self.cpu.get_int_value(deadframe2, 0) == 30 + def test_call_to_c_function(self): from rpython.rlib.libffi import CDLL, types, ArgChain, FUNCFLAG_CDECL from rpython.rtyper.lltypesystem.ll2ctypes import libc_name 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 @@ -651,10 +651,10 @@ _list_all_operations(result, self.operations, omit_finish) return result - def summary(self, adding_insns={}): # for debugging + def summary(self, adding_insns={}, omit_finish=True): # for debugging "NOT_RPYTHON" insns = adding_insns.copy() - for op in self._all_operations(omit_finish=True): + for op in self._all_operations(omit_finish=omit_finish): opname = op.getopname() insns[opname] = insns.get(opname, 0) + 1 return insns @@ -895,10 +895,10 @@ "found %d %r, expected %d" % (found, insn, expected_count)) return insns - def check_resops(self, expected=None, **check): + def check_resops(self, expected=None, omit_finish=True, **check): insns = {} for loop in self.get_all_loops(): - insns = loop.summary(adding_insns=insns) + insns = loop.summary(adding_insns=insns, omit_finish=omit_finish) return self._check_insns(insns, expected, check) def _check_insns(self, insns, expected, check): 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 @@ -153,6 +153,33 @@ assert res == 10180 self.check_resops(setfield_gc=0, getfield_gc=2) + def test_synchronize_in_return_2(self): + myjitdriver = JitDriver(greens = [], reds = ['n', 'xy'], + virtualizables = ['xy']) + class Foo(object): + pass + def g(xy, n): + myjitdriver.jit_merge_point(xy=xy, n=n) + promote_virtualizable(xy, 'inst_x') + xy.inst_x += 1 + return Foo() + def f(n): + xy = self.setup() + promote_virtualizable(xy, 'inst_x') + xy.inst_x = 10000 + m = 10 + foo = None + while m > 0: + foo = g(xy, n) + m -= 1 + assert foo is not None + promote_virtualizable(xy, 'inst_x') + return xy.inst_x + res = self.meta_interp(f, [18]) + assert res == 10010 + self.check_resops(omit_finish=False, + guard_not_forced_2=1, finish=1) + def test_virtualizable_and_greens(self): myjitdriver = JitDriver(greens = ['m'], reds = ['n', 'xy'], virtualizables = ['xy']) diff --git a/rpython/rlib/parsing/makepackrat.py b/rpython/rlib/parsing/makepackrat.py --- a/rpython/rlib/parsing/makepackrat.py +++ b/rpython/rlib/parsing/makepackrat.py @@ -668,7 +668,7 @@ value = new.function(value.func_code, frame.f_globals) if not hasattr(result, key) and key not in forbidden: setattr(result, key, value) - if result.__init__ is object.__init__: + if result.__init__ == object.__init__: result.__init__ = pcls.__dict__['__init__'] result.init_parser = pcls.__dict__['__init__'] result._code = visitor.get_code() diff --git a/rpython/rlib/test/test_runicode.py b/rpython/rlib/test/test_runicode.py --- a/rpython/rlib/test/test_runicode.py +++ b/rpython/rlib/test/test_runicode.py @@ -246,7 +246,8 @@ assert decode('+3AE-', 5, None) == (u'\uDC01', 5) assert decode('+3AE-x', 6, None) == (u'\uDC01x', 6) - assert encode(u'\uD801\U000abcde', 2, None) == '+2AHab9ze-' + u = u'\uD801\U000abcde' + assert encode(u, len(u), None) == '+2AHab9ze-' assert decode('+2AHab9ze-', 10, None) == (u'\uD801\U000abcde', 10) diff --git a/rpython/rlib/unicodedata/test/test_ucd.py b/rpython/rlib/unicodedata/test/test_ucd.py --- a/rpython/rlib/unicodedata/test/test_ucd.py +++ b/rpython/rlib/unicodedata/test/test_ucd.py @@ -1,6 +1,7 @@ -from rpython.rlib.runicode import code_to_unichr +from rpython.rlib.runicode import code_to_unichr, MAXUNICODE from rpython.rlib.unicodedata import unicodedb_5_2_0 from rpython.rtyper.test.tool import BaseRtypingTest +from rpython.translator.c.test.test_genc import compile class TestTranslated(BaseRtypingTest): @@ -15,8 +16,13 @@ print hex(res) assert res == f(1) - def test_code_to_unichr(self): - def f(c): - return code_to_unichr(c) + u'' - res = self.ll_to_unicode(self.interpret(f, [0x10346])) - assert res == u'\U00010346' + +def test_code_to_unichr(): + def f(c): + return ord(code_to_unichr(c)[0]) + f1 = compile(f, [int]) + got = f1(0x12346) + if MAXUNICODE == 65535: + assert got == 0xd808 # first char of a pair + else: + assert got == 0x12346 From noreply at buildbot.pypy.org Sun Sep 22 08:39:00 2013 From: noreply at buildbot.pypy.org (mattip) Date: Sun, 22 Sep 2013 08:39:00 +0200 (CEST) Subject: [pypy-commit] pypy pypy-pyarray: fix tests Message-ID: <20130922063900.0BEF01C12E3@cobra.cs.uni-duesseldorf.de> Author: Matti Picus Branch: pypy-pyarray Changeset: r67050:21c62d1734c4 Date: 2013-09-22 08:36 +0300 http://bitbucket.org/pypy/pypy/changeset/21c62d1734c4/ Log: fix tests diff --git a/pypy/module/test_lib_pypy/numpypy/test_numpy.py b/pypy/module/test_lib_pypy/numpypy/test_numpy.py --- a/pypy/module/test_lib_pypy/numpypy/test_numpy.py +++ b/pypy/module/test_lib_pypy/numpypy/test_numpy.py @@ -96,10 +96,13 @@ def test___all__(self): import numpy - assert '__all__' in numpy + assert '__all__' in dir(numpy) assert 'numpypy' not in dir(numpy) def test_get_include(self): + import sys + if not hasattr(sys, 'pypy_translation_info'): + skip("pypy white-box test") import numpy, os assert 'get_include' in dir(numpy) path = numpy.get_include() From noreply at buildbot.pypy.org Sun Sep 22 08:39:01 2013 From: noreply at buildbot.pypy.org (mattip) Date: Sun, 22 Sep 2013 08:39:01 +0200 (CEST) Subject: [pypy-commit] pypy pypy-pyarray: fix test, change implementation for pendatic exception string, improve test Message-ID: <20130922063901.39CA61C13FB@cobra.cs.uni-duesseldorf.de> Author: Matti Picus Branch: pypy-pyarray Changeset: r67051:c1a7865243c0 Date: 2013-09-22 09:32 +0300 http://bitbucket.org/pypy/pypy/changeset/c1a7865243c0/ Log: fix test, change implementation for pendatic exception string, improve test diff --git a/pypy/module/cpyext/ndarrayobject.py b/pypy/module/cpyext/ndarrayobject.py --- a/pypy/module/cpyext/ndarrayobject.py +++ b/pypy/module/cpyext/ndarrayobject.py @@ -171,8 +171,16 @@ @cpython_api([PyObject, Py_ssize_t, Py_ssize_t, Py_ssize_t], PyObject) def _PyArray_FromObject(space, w_obj, typenum, min_depth, max_depth): - return _PyArray_FromAny(space, w_obj, typenum, min_depth, max_depth, NPY_BEHAVED); - + try: + return _PyArray_FromAny(space, w_obj, typenum, min_depth, max_depth, + 0, None); + except OperationError, e: + if e.match(space, space.w_NotImplementedError): + errstr = space.str_w(e.get_w_value(space)) + errstr = errstr.replace('FromAny','FromObject') + raise OperationError(space.w_NotImplementedError, space.wrap( + errstr)) + raise def get_shape_and_dtype(space, nd, dims, typenum): shape = [] diff --git a/pypy/module/cpyext/test/test_api.py b/pypy/module/cpyext/test/test_api.py --- a/pypy/module/cpyext/test/test_api.py +++ b/pypy/module/cpyext/test/test_api.py @@ -46,7 +46,7 @@ raise Exception("DID NOT RAISE") if getattr(space, 'w_' + expected_exc.__name__) is not operror.w_type: raise Exception("Wrong exception") - state.clear_exception() + return state.clear_exception() def setup_method(self, func): freeze_refcnts(self) diff --git a/pypy/module/cpyext/test/test_ndarrayobject.py b/pypy/module/cpyext/test/test_ndarrayobject.py --- a/pypy/module/cpyext/test/test_ndarrayobject.py +++ b/pypy/module/cpyext/test/test_ndarrayobject.py @@ -96,10 +96,11 @@ def test_FromObject(self, space, api): a = array(space, [10, 5, 3]) - assert api._PyArray_FromObject(a, NULL, 0, 0, 0, NULL) is a - self.raises(space, api, NotImplementedError, api._PyArray_FromObject, - space.wrap(a), space.w_None, space.wrap(0), - space.wrap(3), space.wrap(0), space.w_None) + assert api._PyArray_FromObject(a, None, 0, 0) is a + exc = self.raises(space, api, NotImplementedError, api._PyArray_FromObject, + space.wrap(a), space.wrap(11), space.wrap(0), + space.wrap(3) ) + assert exc.errorstr(space).find('FromObject') >= 0 def test_list_from_fixedptr(self, space, api): A = lltype.GcArray(lltype.Float) From noreply at buildbot.pypy.org Sun Sep 22 08:39:02 2013 From: noreply at buildbot.pypy.org (mattip) Date: Sun, 22 Sep 2013 08:39:02 +0200 (CEST) Subject: [pypy-commit] pypy pypy-pyarray: whoops Message-ID: <20130922063902.5FE601C0203@cobra.cs.uni-duesseldorf.de> Author: Matti Picus Branch: pypy-pyarray Changeset: r67052:e89d93815460 Date: 2013-09-22 09:37 +0300 http://bitbucket.org/pypy/pypy/changeset/e89d93815460/ Log: whoops diff --git a/pypy/module/cpyext/test/test_ndarrayobject.py b/pypy/module/cpyext/test/test_ndarrayobject.py --- a/pypy/module/cpyext/test/test_ndarrayobject.py +++ b/pypy/module/cpyext/test/test_ndarrayobject.py @@ -242,6 +242,7 @@ PyObject * obj2 = PyArray_ZEROS(2, dims2, 11, 0); PyArray_FILLWBYTE(obj2, 42); PyArray_CopyInto(obj2, obj1); + Py_DECREF(obj1); return obj2; ''' ), From noreply at buildbot.pypy.org Sun Sep 22 10:49:59 2013 From: noreply at buildbot.pypy.org (mattip) Date: Sun, 22 Sep 2013 10:49:59 +0200 (CEST) Subject: [pypy-commit] pypy pypy-pyarray: use int not type in test, fix implementation Message-ID: <20130922084959.685DC1C0203@cobra.cs.uni-duesseldorf.de> Author: Matti Picus Branch: pypy-pyarray Changeset: r67053:2e99e8714199 Date: 2013-09-22 11:49 +0300 http://bitbucket.org/pypy/pypy/changeset/2e99e8714199/ Log: use int not type in test, fix implementation diff --git a/pypy/module/cpyext/ndarrayobject.py b/pypy/module/cpyext/ndarrayobject.py --- a/pypy/module/cpyext/ndarrayobject.py +++ b/pypy/module/cpyext/ndarrayobject.py @@ -7,7 +7,7 @@ from rpython.rtyper.lltypesystem import rffi from pypy.module.cpyext.api import cpython_api, Py_ssize_t, CANNOT_FAIL from pypy.module.cpyext.pyobject import PyObject -from pypy.module.micronumpy.interp_numarray import W_NDimArray, convert_to_array, wrap_impl +from pypy.module.micronumpy.interp_numarray import W_NDimArray, array from pypy.module.micronumpy.interp_dtype import get_dtype_cache from pypy.module.micronumpy.arrayimpl.concrete import ConcreteArray from pypy.module.micronumpy.arrayimpl.scalar import Scalar @@ -147,16 +147,16 @@ only used if the array is constructed that way. Almost always this parameter is NULL. """ - if dtype: - raise OperationError(space.w_NotImplementedError, space.wrap( - '_PyArray_FromAny called with not-implemented dtype argument')) if min_depth !=0 or max_depth != 0: raise OperationError(space.w_NotImplementedError, space.wrap( '_PyArray_FromAny called with not-implemented min_dpeth or max_depth argument')) if requirements not in (0, NPY_DEFAULT): raise OperationError(space.w_NotImplementedError, space.wrap( '_PyArray_FromAny called with not-implemented requirements argument')) - w_array = convert_to_array(space, w_obj) + if not dtype: + w_array = array(space, w_obj, copy=False) + else: + w_array = array(space, w_obj, w_dtype=dtype, copy=False) if w_array.is_scalar(): # since PyArray_DATA() fails on scalars, create a 1D array and set empty # shape. So the following combination works for *reading* scalars: @@ -172,7 +172,12 @@ @cpython_api([PyObject, Py_ssize_t, Py_ssize_t, Py_ssize_t], PyObject) def _PyArray_FromObject(space, w_obj, typenum, min_depth, max_depth): try: - return _PyArray_FromAny(space, w_obj, typenum, min_depth, max_depth, + dtype = get_dtype_cache(space).dtypes_by_num[typenum] + except KeyError: + raise OperationError(space.w_ValueError, space.wrap( + '_PyArray_FromObject called with invalid dtype %r' % typenum)) + try: + return _PyArray_FromAny(space, w_obj, dtype, min_depth, max_depth, 0, None); except OperationError, e: if e.match(space, space.w_NotImplementedError): diff --git a/pypy/module/cpyext/test/test_ndarrayobject.py b/pypy/module/cpyext/test/test_ndarrayobject.py --- a/pypy/module/cpyext/test/test_ndarrayobject.py +++ b/pypy/module/cpyext/test/test_ndarrayobject.py @@ -91,15 +91,13 @@ a = array(space, [10, 5, 3]) assert api._PyArray_FromAny(a, NULL, 0, 0, 0, NULL) is a self.raises(space, api, NotImplementedError, api._PyArray_FromAny, - space.wrap(a), space.w_None, space.wrap(0), - space.wrap(3), space.wrap(0), space.w_None) + a, NULL, 0, 3, 0, NULL) def test_FromObject(self, space, api): a = array(space, [10, 5, 3]) - assert api._PyArray_FromObject(a, None, 0, 0) is a + assert api._PyArray_FromObject(a, a.get_dtype().num, 0, 0) is a exc = self.raises(space, api, NotImplementedError, api._PyArray_FromObject, - space.wrap(a), space.wrap(11), space.wrap(0), - space.wrap(3) ) + a, 11, 0, 3) assert exc.errorstr(space).find('FromObject') >= 0 def test_list_from_fixedptr(self, space, api): From noreply at buildbot.pypy.org Sun Sep 22 15:34:15 2013 From: noreply at buildbot.pypy.org (arigo) Date: Sun, 22 Sep 2013 15:34:15 +0200 (CEST) Subject: [pypy-commit] pypy default: Issue #1612: Add operator.__index__(). Message-ID: <20130922133415.E87901C013B@cobra.cs.uni-duesseldorf.de> Author: Armin Rigo Branch: Changeset: r67054:a82f83c4d0a0 Date: 2013-09-22 15:33 +0200 http://bitbucket.org/pypy/pypy/changeset/a82f83c4d0a0/ Log: Issue #1612: Add operator.__index__(). 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 @@ -50,6 +50,7 @@ '__concat__' : 'concat', '__contains__' : 'contains', 'sequenceIncludes' : 'contains', + '__index__' : 'index', '__delitem__' : 'delitem', '__div__' : 'div', '__eq__' : 'eq', 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 @@ -190,3 +190,9 @@ 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_index(self): + import operator + assert operator.index(42) == 42 + assert operator.__index__(42) == 42 + raises(TypeError, operator.index, "abc") From noreply at buildbot.pypy.org Sun Sep 22 17:19:10 2013 From: noreply at buildbot.pypy.org (mattip) Date: Sun, 22 Sep 2013 17:19:10 +0200 (CEST) Subject: [pypy-commit] pypy pypy-pyarray: add tests, rpythonify, use proper w_* api interface Message-ID: <20130922151910.B27591C0203@cobra.cs.uni-duesseldorf.de> Author: Matti Picus Branch: pypy-pyarray Changeset: r67055:ef5c6f72668f Date: 2013-09-22 18:18 +0300 http://bitbucket.org/pypy/pypy/changeset/ef5c6f72668f/ Log: add tests, rpythonify, use proper w_* api interface diff --git a/pypy/module/cpyext/ndarrayobject.py b/pypy/module/cpyext/ndarrayobject.py --- a/pypy/module/cpyext/ndarrayobject.py +++ b/pypy/module/cpyext/ndarrayobject.py @@ -4,11 +4,11 @@ """ from pypy.interpreter.error import OperationError -from rpython.rtyper.lltypesystem import rffi +from rpython.rtyper.lltypesystem import rffi, lltype from pypy.module.cpyext.api import cpython_api, Py_ssize_t, CANNOT_FAIL -from pypy.module.cpyext.pyobject import PyObject +from pypy.module.cpyext.api import PyObject from pypy.module.micronumpy.interp_numarray import W_NDimArray, array -from pypy.module.micronumpy.interp_dtype import get_dtype_cache +from pypy.module.micronumpy.interp_dtype import get_dtype_cache, W_Dtype from pypy.module.micronumpy.arrayimpl.concrete import ConcreteArray from pypy.module.micronumpy.arrayimpl.scalar import Scalar from rpython.rlib.rawstorage import RAW_STORAGE_PTR @@ -113,10 +113,12 @@ assert isinstance(w_array, W_NDimArray) return rffi.cast(rffi.VOIDP, w_array.implementation.storage) +PyArray_Descr = PyObject +NULL = lltype.nullptr(rffi.VOIDP.TO) - at cpython_api([PyObject, rffi.VOIDP, Py_ssize_t, Py_ssize_t, Py_ssize_t, rffi.VOIDP], + at cpython_api([PyObject, PyArray_Descr, Py_ssize_t, Py_ssize_t, Py_ssize_t, rffi.VOIDP], PyObject) -def _PyArray_FromAny(space, w_obj, dtype, min_depth, max_depth, requirements, context): +def _PyArray_FromAny(space, w_obj, w_dtype, min_depth, max_depth, requirements, context): """ This is the main function used to obtain an array from any nested sequence, or object that exposes the array interface, op. The parameters allow specification of the required dtype, the @@ -153,10 +155,7 @@ if requirements not in (0, NPY_DEFAULT): raise OperationError(space.w_NotImplementedError, space.wrap( '_PyArray_FromAny called with not-implemented requirements argument')) - if not dtype: - w_array = array(space, w_obj, copy=False) - else: - w_array = array(space, w_obj, w_dtype=dtype, copy=False) + w_array = array(space, w_obj, w_dtype=w_dtype, copy=False) if w_array.is_scalar(): # since PyArray_DATA() fails on scalars, create a 1D array and set empty # shape. So the following combination works for *reading* scalars: @@ -175,14 +174,14 @@ dtype = get_dtype_cache(space).dtypes_by_num[typenum] except KeyError: raise OperationError(space.w_ValueError, space.wrap( - '_PyArray_FromObject called with invalid dtype %r' % typenum)) + '_PyArray_FromObject called with invalid dtype %d' % typenum)) try: return _PyArray_FromAny(space, w_obj, dtype, min_depth, max_depth, - 0, None); + 0, NULL); except OperationError, e: if e.match(space, space.w_NotImplementedError): errstr = space.str_w(e.get_w_value(space)) - errstr = errstr.replace('FromAny','FromObject') + errstr = '_PyArray_FromObject' + errstr[16:] raise OperationError(space.w_NotImplementedError, space.wrap( errstr)) raise diff --git a/pypy/module/cpyext/test/test_ndarrayobject.py b/pypy/module/cpyext/test/test_ndarrayobject.py --- a/pypy/module/cpyext/test/test_ndarrayobject.py +++ b/pypy/module/cpyext/test/test_ndarrayobject.py @@ -244,6 +244,26 @@ return obj2; ''' ), + ("test_FromAny", "METH_NOARGS", + ''' + npy_intp dims[2] ={2, 3}; + PyObject * obj1 = PyArray_SimpleNew(2, dims, 1); + PyArray_FILLWBYTE(obj1, 42); + PyObject * obj2 = _PyArray_FromAny(obj1, NULL, 0, 0, 0, NULL); + Py_DECREF(obj1); + return obj2; + ''' + ), + ("test_FromObject", "METH_NOARGS", + ''' + npy_intp dims[2] ={2, 3}; + PyObject * obj1 = PyArray_SimpleNew(2, dims, 1); + PyArray_FILLWBYTE(obj1, 42); + PyObject * obj2 = _PyArray_FromObject(obj1, 12, 0, 0); + Py_DECREF(obj1); + return obj2; + ''' + ), ], prologue='#include ') arr = mod.test_simplenew() assert arr.shape == (2, 3) @@ -254,3 +274,6 @@ assert (arr == 42).all() arr = mod.test_copy() assert (arr == 0).all() + #Make sure these work without errors + arr = mod.test_FromAny() + arr = mod.test_FromObject() From noreply at buildbot.pypy.org Sun Sep 22 21:24:47 2013 From: noreply at buildbot.pypy.org (rlamy) Date: Sun, 22 Sep 2013 21:24:47 +0200 (CEST) Subject: [pypy-commit] pypy less-stringly-ops: Simplify creation of hlop proxy methods on FlowObjSpace Message-ID: <20130922192447.14FD31C0203@cobra.cs.uni-duesseldorf.de> Author: Ronan Lamy Branch: less-stringly-ops Changeset: r67056:3ab58f53ee10 Date: 2013-09-22 02:40 +0100 http://bitbucket.org/pypy/pypy/changeset/3ab58f53ee10/ Log: Simplify creation of hlop proxy methods on FlowObjSpace diff --git a/rpython/flowspace/objspace.py b/rpython/flowspace/objspace.py --- a/rpython/flowspace/objspace.py +++ b/rpython/flowspace/objspace.py @@ -272,14 +272,9 @@ raise FlowingError("global name '%s' is not defined" % varname) return const(value) -def make_op(cls): - def generic_operator(self, *args): - return cls(*args).eval(self.frame) - return generic_operator - for cls in op.__dict__.values(): if getattr(FlowObjSpace, cls.opname, None) is None: - setattr(FlowObjSpace, cls.opname, make_op(cls)) + setattr(FlowObjSpace, cls.opname, cls.make_sc()) def build_flow(func, space=FlowObjSpace()): diff --git a/rpython/flowspace/operation.py b/rpython/flowspace/operation.py --- a/rpython/flowspace/operation.py +++ b/rpython/flowspace/operation.py @@ -25,8 +25,8 @@ # this is an incomplete list of true constants. # if we add much more, a dedicated class # might be considered for special objects. - } } +} class _OpHolder(object): pass @@ -36,6 +36,7 @@ class HLOperation(SpaceOperation): pure = False + def __init__(self, *args): if len(args) != self.arity: raise TypeError(self.opname + " got the wrong number of arguments") @@ -54,9 +55,7 @@ else: raise Exception("should call %r with exactly %d arguments" % ( cls.opname, cls.arity)) - # completely replace the call with the underlying - # operation and its limited implicit exceptions semantic - return getattr(space, cls.opname)(*args_w) + return cls(*args_w).eval(space.frame) return sc_operator def eval(self, frame): From noreply at buildbot.pypy.org Sun Sep 22 21:24:48 2013 From: noreply at buildbot.pypy.org (rlamy) Date: Sun, 22 Sep 2013 21:24:48 +0200 (CEST) Subject: [pypy-commit] pypy less-stringly-ops: kill unused argument 'symbol' in add_operator() Message-ID: <20130922192448.3CEBB1C0203@cobra.cs.uni-duesseldorf.de> Author: Ronan Lamy Branch: less-stringly-ops Changeset: r67057:357a7e753e92 Date: 2013-09-22 03:21 +0100 http://bitbucket.org/pypy/pypy/changeset/357a7e753e92/ Log: kill unused argument 'symbol' in add_operator() diff --git a/rpython/flowspace/operation.py b/rpython/flowspace/operation.py --- a/rpython/flowspace/operation.py +++ b/rpython/flowspace/operation.py @@ -102,7 +102,7 @@ pass -def add_operator(name, arity, symbol, pyfunc=None, pure=False, ovf=False): +def add_operator(name, arity, pyfunc=None, pure=False, ovf=False): operator_func = getattr(operator, name, None) base_cls = PureOperation if pure else HLOperation cls = type(name, (base_cls,), {'opname': name, 'arity': arity, @@ -119,7 +119,7 @@ if ovf: from rpython.rlib.rarithmetic import ovfcheck ovf_func = lambda *args: ovfcheck(cls.pyfunc(*args)) - add_operator(name + '_ovf', arity, symbol, pyfunc=ovf_func) + add_operator(name + '_ovf', arity, pyfunc=ovf_func) # ____________________________________________________________ @@ -225,79 +225,78 @@ raise ValueError("this is not supported") -add_operator('is_', 2, 'is', pure=True) -add_operator('id', 1, 'id', pyfunc=id) -add_operator('type', 1, 'type', pyfunc=new_style_type, pure=True) -add_operator('issubtype', 2, 'issubtype', pyfunc=issubclass, pure=True) # not for old-style classes -add_operator('repr', 1, 'repr', pyfunc=repr, pure=True) -add_operator('str', 1, 'str', pyfunc=str, pure=True) -add_operator('format', 2, 'format', pyfunc=unsupported) -add_operator('len', 1, 'len', pyfunc=len, pure=True) -add_operator('hash', 1, 'hash', pyfunc=hash) -add_operator('setattr', 3, 'setattr', pyfunc=setattr) -add_operator('delattr', 2, 'delattr', pyfunc=delattr) -add_operator('getitem', 2, 'getitem', pure=True) -add_operator('setitem', 3, 'setitem') -add_operator('delitem', 2, 'delitem') -add_operator('getslice', 3, 'getslice', pyfunc=do_getslice, pure=True) -add_operator('setslice', 4, 'setslice', pyfunc=do_setslice) -add_operator('delslice', 3, 'delslice', pyfunc=do_delslice) -add_operator('trunc', 1, 'trunc', pyfunc=unsupported) -add_operator('pos', 1, 'pos', pure=True) -add_operator('neg', 1, 'neg', pure=True, ovf=True) -add_operator('bool', 1, 'truth', pyfunc=bool, pure=True) +add_operator('is_', 2, pure=True) +add_operator('id', 1, pyfunc=id) +add_operator('type', 1, pyfunc=new_style_type, pure=True) +add_operator('issubtype', 2, pyfunc=issubclass, pure=True) # not for old-style classes +add_operator('repr', 1, pyfunc=repr, pure=True) +add_operator('str', 1, pyfunc=str, pure=True) +add_operator('format', 2, pyfunc=unsupported) +add_operator('len', 1, pyfunc=len, pure=True) +add_operator('hash', 1, pyfunc=hash) +add_operator('setattr', 3, pyfunc=setattr) +add_operator('delattr', 2, pyfunc=delattr) +add_operator('getitem', 2, pure=True) +add_operator('setitem', 3) +add_operator('delitem', 2) +add_operator('getslice', 3, pyfunc=do_getslice, pure=True) +add_operator('setslice', 4, pyfunc=do_setslice) +add_operator('delslice', 3, pyfunc=do_delslice) +add_operator('trunc', 1, pyfunc=unsupported) +add_operator('pos', 1, pure=True) +add_operator('neg', 1, pure=True, ovf=True) +add_operator('bool', 1, pyfunc=bool, pure=True) op.is_true = op.nonzero = op.bool # for llinterp -add_operator('abs', 1, 'abs', pyfunc=abs, pure=True, ovf=True) -add_operator('hex', 1, 'hex', pyfunc=hex, pure=True) -add_operator('oct', 1, 'oct', pyfunc=oct, pure=True) -add_operator('ord', 1, 'ord', pyfunc=ord, pure=True) -add_operator('invert', 1, '~', pure=True) -add_operator('add', 2, '+', pure=True, ovf=True) -add_operator('sub', 2, '-', pure=True, ovf=True) -add_operator('mul', 2, '*', pure=True, ovf=True) -add_operator('truediv', 2, '/', pure=True) -add_operator('floordiv', 2, '//', pure=True, ovf=True) -add_operator('div', 2, 'div', pure=True, ovf=True) -add_operator('mod', 2, '%', pure=True, ovf=True) -add_operator('divmod', 2, 'divmod', pyfunc=divmod, pure=True) -add_operator('pow', 3, '**', pyfunc=pow, pure=True) -add_operator('lshift', 2, '<<', pure=True, ovf=True) -add_operator('rshift', 2, '>>', pure=True) -add_operator('and_', 2, '&', pure=True) -add_operator('or_', 2, '|', pure=True) -add_operator('xor', 2, '^', pure=True) -add_operator('int', 1, 'int', pyfunc=do_int, pure=True) -add_operator('index', 1, 'index', pyfunc=do_index, pure=True) -add_operator('float', 1, 'float', pyfunc=do_float, pure=True) -add_operator('long', 1, 'long', pyfunc=do_long, pure=True) -add_operator('inplace_add', 2, '+=', pyfunc=inplace_add) -add_operator('inplace_sub', 2, '-=', pyfunc=inplace_sub) -add_operator('inplace_mul', 2, '*=', pyfunc=inplace_mul) -add_operator('inplace_truediv', 2, '/=', pyfunc=inplace_truediv) -add_operator('inplace_floordiv', 2, '//=', pyfunc=inplace_floordiv) -add_operator('inplace_div', 2, 'div=', pyfunc=inplace_div) -add_operator('inplace_mod', 2, '%=', pyfunc=inplace_mod) -add_operator('inplace_pow', 2, '**=', pyfunc=inplace_pow) -add_operator('inplace_lshift', 2, '<<=', pyfunc=inplace_lshift) -add_operator('inplace_rshift', 2, '>>=', pyfunc=inplace_rshift) -add_operator('inplace_and', 2, '&=', pyfunc=inplace_and) -add_operator('inplace_or', 2, '|=', pyfunc=inplace_or) -add_operator('inplace_xor', 2, '^=', pyfunc=inplace_xor) -add_operator('lt', 2, '<', pure=True) -add_operator('le', 2, '<=', pure=True) -add_operator('eq', 2, '==', pure=True) -add_operator('ne', 2, '!=', pure=True) -add_operator('gt', 2, '>', pure=True) -add_operator('ge', 2, '>=', pure=True) -add_operator('cmp', 2, 'cmp', pyfunc=cmp, pure=True) # rich cmps preferred -add_operator('coerce', 2, 'coerce', pyfunc=coerce, pure=True) -add_operator('contains', 2, 'contains', pure=True) -#add_operator('call', 3, 'call') -add_operator('get', 3, 'get', pyfunc=get, pure=True) -add_operator('set', 3, 'set', pyfunc=set) -add_operator('delete', 2, 'delete', pyfunc=delete) -add_operator('userdel', 1, 'del', pyfunc=userdel) -add_operator('buffer', 1, 'buffer', pyfunc=buffer, pure=True) # see buffer.py +add_operator('abs', 1, pyfunc=abs, pure=True, ovf=True) +add_operator('hex', 1, pyfunc=hex, pure=True) +add_operator('oct', 1, pyfunc=oct, pure=True) +add_operator('ord', 1, pyfunc=ord, pure=True) +add_operator('invert', 1, pure=True) +add_operator('add', 2, pure=True, ovf=True) +add_operator('sub', 2, pure=True, ovf=True) +add_operator('mul', 2, pure=True, ovf=True) +add_operator('truediv', 2, pure=True) +add_operator('floordiv', 2, pure=True, ovf=True) +add_operator('div', 2, pure=True, ovf=True) +add_operator('mod', 2, pure=True, ovf=True) +add_operator('divmod', 2, pyfunc=divmod, pure=True) +add_operator('pow', 3, pyfunc=pow, pure=True) +add_operator('lshift', 2, pure=True, ovf=True) +add_operator('rshift', 2, pure=True) +add_operator('and_', 2, pure=True) +add_operator('or_', 2, pure=True) +add_operator('xor', 2, pure=True) +add_operator('int', 1, pyfunc=do_int, pure=True) +add_operator('index', 1, pyfunc=do_index, pure=True) +add_operator('float', 1, pyfunc=do_float, pure=True) +add_operator('long', 1, pyfunc=do_long, pure=True) +add_operator('inplace_add', 2, pyfunc=inplace_add) +add_operator('inplace_sub', 2, pyfunc=inplace_sub) +add_operator('inplace_mul', 2, pyfunc=inplace_mul) +add_operator('inplace_truediv', 2, pyfunc=inplace_truediv) +add_operator('inplace_floordiv', 2, pyfunc=inplace_floordiv) +add_operator('inplace_div', 2, pyfunc=inplace_div) +add_operator('inplace_mod', 2, pyfunc=inplace_mod) +add_operator('inplace_pow', 2, pyfunc=inplace_pow) +add_operator('inplace_lshift', 2, pyfunc=inplace_lshift) +add_operator('inplace_rshift', 2, pyfunc=inplace_rshift) +add_operator('inplace_and', 2, pyfunc=inplace_and) +add_operator('inplace_or', 2, pyfunc=inplace_or) +add_operator('inplace_xor', 2, pyfunc=inplace_xor) +add_operator('lt', 2, pure=True) +add_operator('le', 2, pure=True) +add_operator('eq', 2, pure=True) +add_operator('ne', 2, pure=True) +add_operator('gt', 2, pure=True) +add_operator('ge', 2, pure=True) +add_operator('cmp', 2, pyfunc=cmp, pure=True) # rich cmps preferred +add_operator('coerce', 2, pyfunc=coerce, pure=True) +add_operator('contains', 2, pure=True) +add_operator('get', 3, pyfunc=get, pure=True) +add_operator('set', 3, pyfunc=set) +add_operator('delete', 2, pyfunc=delete) +add_operator('userdel', 1, pyfunc=userdel) +add_operator('buffer', 1, pyfunc=buffer, pure=True) # see buffer.py class Iter(HLOperation): opname = 'iter' From noreply at buildbot.pypy.org Sun Sep 22 21:24:49 2013 From: noreply at buildbot.pypy.org (rlamy) Date: Sun, 22 Sep 2013 21:24:49 +0200 (CEST) Subject: [pypy-commit] pypy less-stringly-ops: remove special cases in HLOperation.make_sc() Message-ID: <20130922192449.603EB1C0203@cobra.cs.uni-duesseldorf.de> Author: Ronan Lamy Branch: less-stringly-ops Changeset: r67058:c5840ab6589e Date: 2013-09-22 06:58 +0100 http://bitbucket.org/pypy/pypy/changeset/c5840ab6589e/ Log: remove special cases in HLOperation.make_sc() diff --git a/rpython/flowspace/operation.py b/rpython/flowspace/operation.py --- a/rpython/flowspace/operation.py +++ b/rpython/flowspace/operation.py @@ -47,14 +47,6 @@ @classmethod def make_sc(cls): def sc_operator(space, *args_w): - if len(args_w) != cls.arity: - if cls is op.pow and len(args_w) == 2: - args_w = list(args_w) + [Constant(None)] - elif cls is op.getattr and len(args_w) == 3: - return space.frame.do_operation('simple_call', Constant(getattr), *args_w) - else: - raise Exception("should call %r with exactly %d arguments" % ( - cls.opname, cls.arity)) return cls(*args_w).eval(space.frame) return sc_operator @@ -260,7 +252,6 @@ add_operator('div', 2, pure=True, ovf=True) add_operator('mod', 2, pure=True, ovf=True) add_operator('divmod', 2, pyfunc=divmod, pure=True) -add_operator('pow', 3, pyfunc=pow, pure=True) add_operator('lshift', 2, pure=True, ovf=True) add_operator('rshift', 2, pure=True) add_operator('and_', 2, pure=True) @@ -298,6 +289,20 @@ add_operator('userdel', 1, pyfunc=userdel) add_operator('buffer', 1, pyfunc=buffer, pure=True) # see buffer.py +class Pow(PureOperation): + opname = 'pow' + arity = 3 + can_overflow = False + canraise = [] + pyfunc = pow + + def __init__(self, w_base, w_exponent, w_mod=const(None)): + self.args = [w_base, w_exponent, w_mod] + self.result = Variable() + self.offset = -1 +op.pow = Pow + + class Iter(HLOperation): opname = 'iter' arity = 1 @@ -372,6 +377,8 @@ # Other functions that get directly translated to SpaceOperators func2op[type] = op.type func2op[operator.truth] = op.bool +func2op[pow] = op.pow +func2op[operator.pow] = op.pow func2op[__builtin__.iter] = op.iter func2op[getattr] = op.getattr func2op[__builtin__.next] = op.next diff --git a/rpython/flowspace/specialcase.py b/rpython/flowspace/specialcase.py --- a/rpython/flowspace/specialcase.py +++ b/rpython/flowspace/specialcase.py @@ -37,6 +37,14 @@ return space.frame.do_operation('simple_call', const(isinstance), w_instance, w_type) + at register_flow_sc(getattr) +def sc_getattr(space, w_obj, w_index, w_default=None): + if w_default is not None: + return space.frame.do_operation('simple_call', const(getattr), w_obj, + w_index, w_default) + else: + return space.getattr(w_obj, w_index) + # _________________________________________________________________________ # a simplified version of the basic printing routines, for RPython programs class StdOutBuffer: From noreply at buildbot.pypy.org Sun Sep 22 21:24:51 2013 From: noreply at buildbot.pypy.org (rlamy) Date: Sun, 22 Sep 2013 21:24:51 +0200 (CEST) Subject: [pypy-commit] pypy less-stringly-ops: Allow passing empty exceptions to guessexception() Message-ID: <20130922192451.377861C0203@cobra.cs.uni-duesseldorf.de> Author: Ronan Lamy Branch: less-stringly-ops Changeset: r67059:c5e357896529 Date: 2013-09-22 07:28 +0100 http://bitbucket.org/pypy/pypy/changeset/c5e357896529/ Log: Allow passing empty exceptions to guessexception() diff --git a/rpython/flowspace/flowcontext.py b/rpython/flowspace/flowcontext.py --- a/rpython/flowspace/flowcontext.py +++ b/rpython/flowspace/flowcontext.py @@ -434,14 +434,15 @@ def do_op(self, op): self.record(op) - if op.canraise: - self.guessexception(op.canraise) + self.guessexception(op.canraise) return op.result def guessexception(self, exceptions, force=False): """ Catch possible exceptions implicitly. """ + if not exceptions: + return if not force and not any(isinstance(block, (ExceptBlock, FinallyBlock)) for block in self.blockstack): # The implicit exception wouldn't be caught and would later get From noreply at buildbot.pypy.org Sun Sep 22 21:24:52 2013 From: noreply at buildbot.pypy.org (rlamy) Date: Sun, 22 Sep 2013 21:24:52 +0200 (CEST) Subject: [pypy-commit] pypy less-stringly-ops: Extract helper from FlowObjSpace.call_args() Message-ID: <20130922192452.6391E1C0203@cobra.cs.uni-duesseldorf.de> Author: Ronan Lamy Branch: less-stringly-ops Changeset: r67060:09873ad29c60 Date: 2013-09-22 07:35 +0100 http://bitbucket.org/pypy/pypy/changeset/09873ad29c60/ Log: Extract helper from FlowObjSpace.call_args() diff --git a/rpython/flowspace/objspace.py b/rpython/flowspace/objspace.py --- a/rpython/flowspace/objspace.py +++ b/rpython/flowspace/objspace.py @@ -246,7 +246,10 @@ else: args_w = args.arguments_w w_res = self.frame.do_operation('simple_call', w_callable, *args_w) + self.frame.guessexception(self._callable_exceptions(w_callable)) + return w_res + def _callable_exceptions(self, w_callable): if isinstance(w_callable, Constant): c = w_callable.value if (isinstance(c, (types.BuiltinFunctionType, @@ -254,12 +257,10 @@ types.ClassType, types.TypeType)) and c.__module__ in ['__builtin__', 'exceptions']): - if c in builtins_exceptions: - self.frame.guessexception(builtins_exceptions[c]) - return w_res + return builtins_exceptions.get(c, []) # *any* exception for non-builtins - self.frame.guessexception([Exception]) - return w_res + return [Exception] + def find_global(self, w_globals, varname): try: From noreply at buildbot.pypy.org Sun Sep 22 21:24:53 2013 From: noreply at buildbot.pypy.org (rlamy) Date: Sun, 22 Sep 2013 21:24:53 +0200 (CEST) Subject: [pypy-commit] pypy less-stringly-ops: kill FlowObjSpace.unpackiterable() Message-ID: <20130922192453.7C12F1C0203@cobra.cs.uni-duesseldorf.de> Author: Ronan Lamy Branch: less-stringly-ops Changeset: r67061:199438138ea5 Date: 2013-09-22 07:53 +0100 http://bitbucket.org/pypy/pypy/changeset/199438138ea5/ Log: kill FlowObjSpace.unpackiterable() diff --git a/rpython/flowspace/argument.py b/rpython/flowspace/argument.py --- a/rpython/flowspace/argument.py +++ b/rpython/flowspace/argument.py @@ -1,7 +1,7 @@ """ Arguments objects. """ - +from rpython.flowspace.model import const class Signature(object): _immutable_ = True @@ -95,3 +95,10 @@ if shape_star: data_w.append(self.w_stararg) return (shape_cnt, shape_keys, shape_star, shape_stst), data_w + + def as_list(self): + assert not self.keywords + if self.w_stararg is None: + return self.arguments_w + else: + return self.arguments_w + [const(x) for x in self.w_stararg.value] diff --git a/rpython/flowspace/objspace.py b/rpython/flowspace/objspace.py --- a/rpython/flowspace/objspace.py +++ b/rpython/flowspace/objspace.py @@ -8,8 +8,8 @@ from inspect import CO_NEWLOCALS from rpython.flowspace.argument import CallSpec -from rpython.flowspace.model import (Constant, Variable, WrapException, - UnwrapException, checkgraph, const, FSException) +from rpython.flowspace.model import (Constant, Variable, checkgraph, const, + FSException) from rpython.flowspace.bytecode import HostCode from rpython.flowspace.operation import op, NOT_REALLY_CONST from rpython.flowspace.flowcontext import (FlowSpaceFrame, fixeggblocks, @@ -121,8 +121,8 @@ w_real_class = const(rstackovf._StackOverflow) return frame.guessbool(self.issubtype(w_exc_type, w_real_class)) # checking a tuple of classes - for w_klass in self.unpackiterable(w_check_class): - if self.exception_match(w_exc_type, w_klass): + for klass in w_check_class.value: + if self.exception_match(w_exc_type, const(klass)): return True return False @@ -157,13 +157,6 @@ w_type = self.type(w_value) return FSException(w_type, w_value) - def unpackiterable(self, w_iterable): - if isinstance(w_iterable, Constant): - l = w_iterable.value - return [const(x) for x in l] - else: - raise UnwrapException("cannot unpack a Variable iterable ") - def unpack_sequence(self, w_iterable, expected_length): if isinstance(w_iterable, Constant): l = list(w_iterable.value) @@ -183,7 +176,6 @@ def not_(self, w_obj): return const(not self.frame.guessbool(self.bool(w_obj))) - def import_name(self, name, glob=None, loc=None, frm=None, level=-1): try: mod = __import__(name, glob, loc, frm, level) @@ -229,23 +221,18 @@ except (KeyError, TypeError): pass else: - assert args.keywords == {}, "should not call %r with keyword arguments" % (fn,) - if args.w_stararg is not None: - args_w = args.arguments_w + self.unpackiterable(args.w_stararg) - else: - args_w = args.arguments_w - return sc(self, *args_w) + if args.keywords: + raise FlowingError( + "should not call %r with keyword arguments" % (fn,)) + return sc(self, *args.as_list()) if args.keywords or isinstance(args.w_stararg, Variable): shape, args_w = args.flatten() w_res = self.frame.do_operation('call_args', w_callable, Constant(shape), *args_w) else: - if args.w_stararg is not None: - args_w = args.arguments_w + self.unpackiterable(args.w_stararg) - else: - args_w = args.arguments_w - w_res = self.frame.do_operation('simple_call', w_callable, *args_w) + w_res = self.frame.do_operation( + 'simple_call', w_callable, *args.as_list()) self.frame.guessexception(self._callable_exceptions(w_callable)) return w_res @@ -261,7 +248,6 @@ # *any* exception for non-builtins return [Exception] - def find_global(self, w_globals, varname): try: value = w_globals.value[varname] From noreply at buildbot.pypy.org Sun Sep 22 21:24:54 2013 From: noreply at buildbot.pypy.org (rlamy) Date: Sun, 22 Sep 2013 21:24:54 +0200 (CEST) Subject: [pypy-commit] pypy less-stringly-ops: Add op.simple_call and op.call_args Message-ID: <20130922192454.A09031C0203@cobra.cs.uni-duesseldorf.de> Author: Ronan Lamy Branch: less-stringly-ops Changeset: r67062:2e89f6de1470 Date: 2013-09-22 19:14 +0100 http://bitbucket.org/pypy/pypy/changeset/2e89f6de1470/ Log: Add op.simple_call and op.call_args diff --git a/rpython/flowspace/flowcontext.py b/rpython/flowspace/flowcontext.py --- a/rpython/flowspace/flowcontext.py +++ b/rpython/flowspace/flowcontext.py @@ -933,7 +933,7 @@ arguments = self.popvalues(n_arguments) args = CallSpec(arguments, keywords, w_star, w_starstar) w_function = self.popvalue() - w_result = self.space.call_args(w_function, args) + w_result = self.space.call(w_function, args) self.pushvalue(w_result) def CALL_FUNCTION(self, oparg): diff --git a/rpython/flowspace/objspace.py b/rpython/flowspace/objspace.py --- a/rpython/flowspace/objspace.py +++ b/rpython/flowspace/objspace.py @@ -21,15 +21,6 @@ from rpython.rlib import rstackovf -# built-ins that can always raise exceptions -builtins_exceptions = { - int: [ValueError], - float: [ValueError], - chr: [ValueError], - unichr: [ValueError], - unicode: [UnicodeDecodeError], -} - def _assert_rpythonic(func): """Raise ValueError if ``func`` is obviously not RPython""" @@ -203,14 +194,14 @@ def call_function(self, w_func, *args_w): args = CallSpec(list(args_w)) - return self.call_args(w_func, args) + return self.call(w_func, args) def appcall(self, func, *args_w): """Call an app-level RPython function directly""" w_func = const(func) return self.frame.do_operation('simple_call', w_func, *args_w) - def call_args(self, w_callable, args): + def call(self, w_callable, args): if isinstance(w_callable, Constant): fn = w_callable.value if hasattr(fn, "_flowspace_rewrite_directly_as_"): @@ -228,25 +219,10 @@ if args.keywords or isinstance(args.w_stararg, Variable): shape, args_w = args.flatten() - w_res = self.frame.do_operation('call_args', w_callable, - Constant(shape), *args_w) + hlop = op.call_args(w_callable, Constant(shape), *args_w) else: - w_res = self.frame.do_operation( - 'simple_call', w_callable, *args.as_list()) - self.frame.guessexception(self._callable_exceptions(w_callable)) - return w_res - - def _callable_exceptions(self, w_callable): - if isinstance(w_callable, Constant): - c = w_callable.value - if (isinstance(c, (types.BuiltinFunctionType, - types.BuiltinMethodType, - types.ClassType, - types.TypeType)) and - c.__module__ in ['__builtin__', 'exceptions']): - return builtins_exceptions.get(c, []) - # *any* exception for non-builtins - return [Exception] + hlop = op.simple_call(w_callable, *args.as_list()) + return self.frame.do_op(hlop) def find_global(self, w_globals, varname): try: diff --git a/rpython/flowspace/operation.py b/rpython/flowspace/operation.py --- a/rpython/flowspace/operation.py +++ b/rpython/flowspace/operation.py @@ -7,6 +7,7 @@ import __future__ import operator import sys +import types from rpython.rlib.unroll import unrolling_iterable, _unroller from rpython.tool.sourcetools import compile2 from rpython.flowspace.model import (Constant, WrapException, const, Variable, @@ -28,6 +29,13 @@ } } +# built-ins that can always raise exceptions +builtins_exceptions = { + chr: [ValueError], + unichr: [ValueError], + unicode: [UnicodeDecodeError], +} + class _OpHolder(object): pass op = _OpHolder() @@ -38,8 +46,6 @@ pure = False def __init__(self, *args): - if len(args) != self.arity: - raise TypeError(self.opname + " got the wrong number of arguments") self.args = list(args) self.result = Variable() self.offset = -1 @@ -372,7 +378,29 @@ pass op.getattr = GetAttr +class CallOp(HLOperation): + @property + def canraise(self): + w_callable = self.args[0] + if isinstance(w_callable, Constant): + c = w_callable.value + if (isinstance(c, (types.BuiltinFunctionType, + types.BuiltinMethodType, + types.ClassType, + types.TypeType)) and + c.__module__ in ['__builtin__', 'exceptions']): + return builtins_exceptions.get(c, []) + # *any* exception for non-builtins + return [Exception] +class SimpleCall(CallOp): + opname = 'simple_call' +op.simple_call = SimpleCall + + +class CallArgs(CallOp): + opname = 'call_args' +op.call_args = CallArgs # Other functions that get directly translated to SpaceOperators func2op[type] = op.type From noreply at buildbot.pypy.org Sun Sep 22 21:24:58 2013 From: noreply at buildbot.pypy.org (rlamy) Date: Sun, 22 Sep 2013 21:24:58 +0200 (CEST) Subject: [pypy-commit] pypy less-stringly-ops: hg merge default Message-ID: <20130922192458.AC9371C0203@cobra.cs.uni-duesseldorf.de> Author: Ronan Lamy Branch: less-stringly-ops Changeset: r67063:25e171ca825f Date: 2013-09-22 20:24 +0100 http://bitbucket.org/pypy/pypy/changeset/25e171ca825f/ Log: hg merge default diff too long, truncating to 2000 out of 5610 lines diff --git a/lib-python/2.7/argparse.py b/lib-python/2.7/argparse.py --- a/lib-python/2.7/argparse.py +++ b/lib-python/2.7/argparse.py @@ -1780,7 +1780,19 @@ # error if this argument is not allowed with other previously # seen arguments, assuming that actions that use the default # value don't really count as "present" - if argument_values is not action.default: + + # XXX PyPy bug-to-bug compatibility: "is" on primitive types + # is not consistent in CPython. We'll assume it is close + # enough for ints (which is true only for "small ints"), but + # for floats and longs and complexes we'll go for the option + # of forcing "is" to say False, like it usually does on + # CPython. A fix is pending on CPython trunk + # (http://bugs.python.org/issue18943) but that might change + # the details of the semantics and so not be applied to 2.7. + # See the line AA below. + + if (argument_values is not action.default or + type(argument_values) in (float, long, complex)): # AA seen_non_default_actions.add(action) for conflict_action in action_conflicts.get(action, []): if conflict_action in seen_non_default_actions: diff --git a/lib-python/2.7/uuid.py b/lib-python/2.7/uuid.py --- a/lib-python/2.7/uuid.py +++ b/lib-python/2.7/uuid.py @@ -128,10 +128,10 @@ """ if hex is not None: - if (bytes is not None or bytes_le is not None or fields is not None - or int is not None): - raise TypeError('if the hex argument is given, bytes, bytes_le, fields,' - ' and int need to be None') + if (bytes is not None or bytes_le is not None or + fields is not None or int is not None): + raise TypeError('if the hex argument is given, bytes,' + ' bytes_le, fields, and int need to be None') hex = hex.replace('urn:', '').replace('uuid:', '') hex = hex.strip('{}').replace('-', '') if len(hex) != 32: @@ -139,8 +139,8 @@ int = long(hex, 16) elif bytes_le is not None: if bytes is not None or fields is not None or int is not None: - raise TypeError('if the bytes_le argument is given, bytes, fields,' - ' and int need to be None') + raise TypeError('if the bytes_le argument is given, bytes,' + ' fields, and int need to be None') if len(bytes_le) != 16: raise ValueError('bytes_le is not a 16-char string') bytes = (bytes_le[3] + bytes_le[2] + bytes_le[1] + bytes_le[0] + @@ -150,15 +150,16 @@ struct.unpack('>Q', bytes[8:])[0]) elif bytes is not None: if fields is not None or int is not None: - raise TypeError('if the bytes argument is given, fields' - ' and int need to be None') + raise TypeError('if the bytes argument is given, fields ' + 'and int need to be None') if len(bytes) != 16: raise ValueError('bytes is not a 16-char string') int = (struct.unpack('>Q', bytes[:8])[0] << 64 | struct.unpack('>Q', bytes[8:])[0]) elif fields is not None: if int is not None: - raise TypeError('if the fields argument is given, int needs to be None') + raise TypeError('if the fields argument is given, int needs' + ' to be None') if len(fields) != 6: raise ValueError('fields is not a 6-tuple') (time_low, time_mid, time_hi_version, diff --git a/lib_pypy/_curses.py b/lib_pypy/_curses.py --- a/lib_pypy/_curses.py +++ b/lib_pypy/_curses.py @@ -1,6 +1,9 @@ """Reimplementation of the standard extension module '_curses' using cffi.""" import sys +if sys.platform == 'win32': + #This module does not exist in windows + raise ImportError('No module named _curses') from functools import wraps from cffi import FFI diff --git a/lib_pypy/_tkinter/__init__.py b/lib_pypy/_tkinter/__init__.py --- a/lib_pypy/_tkinter/__init__.py +++ b/lib_pypy/_tkinter/__init__.py @@ -22,6 +22,7 @@ READABLE = tklib.TCL_READABLE WRITABLE = tklib.TCL_WRITABLE EXCEPTION = tklib.TCL_EXCEPTION +DONT_WAIT = tklib.TCL_DONT_WAIT def create(screenName=None, baseName=None, className=None, interactive=False, wantobjects=False, wantTk=True, diff --git a/lib_pypy/_tkinter/app.py b/lib_pypy/_tkinter/app.py --- a/lib_pypy/_tkinter/app.py +++ b/lib_pypy/_tkinter/app.py @@ -4,7 +4,23 @@ from . import TclError from .tclobj import TclObject, FromObj, AsObj, TypeCache +import contextlib import sys +import threading +import time + + +class _DummyLock(object): + "A lock-like object that does not do anything" + def acquire(self): + pass + def release(self): + pass + def __enter__(self): + pass + def __exit__(self, *exc): + pass + def varname_converter(input): if isinstance(input, TclObject): @@ -37,17 +53,18 @@ def PythonCmd(clientData, interp, argc, argv): self = tkffi.from_handle(clientData) assert self.app.interp == interp - try: - args = [tkffi.string(arg) for arg in argv[1:argc]] - result = self.func(*args) - obj = AsObj(result) - tklib.Tcl_SetObjResult(interp, obj) - except: - self.app.errorInCmd = True - self.app.exc_info = sys.exc_info() - return tklib.TCL_ERROR - else: - return tklib.TCL_OK + with self.app._tcl_lock_released(): + try: + args = [tkffi.string(arg) for arg in argv[1:argc]] + result = self.func(*args) + obj = AsObj(result) + tklib.Tcl_SetObjResult(interp, obj) + except: + self.app.errorInCmd = True + self.app.exc_info = sys.exc_info() + return tklib.TCL_ERROR + else: + return tklib.TCL_OK @tkffi.callback("Tcl_CmdDeleteProc") def PythonCmdDelete(clientData): @@ -58,6 +75,8 @@ class TkApp(object): + _busywaitinterval = 0.02 # 20ms. + def __new__(cls, screenName, baseName, className, interactive, wantobjects, wantTk, sync, use): if not wantobjects: @@ -73,6 +92,12 @@ self.quitMainLoop = False self.errorInCmd = False + if not self.threaded: + # TCL is not thread-safe, calls needs to be serialized. + self._tcl_lock = threading.Lock() + else: + self._tcl_lock = _DummyLock() + self._typeCache = TypeCache() self._commands = {} @@ -133,6 +158,13 @@ if self.threaded and self.thread_id != tklib.Tcl_GetCurrentThread(): raise RuntimeError("Calling Tcl from different appartment") + @contextlib.contextmanager + def _tcl_lock_released(self): + "Context manager to temporarily release the tcl lock." + self._tcl_lock.release() + yield + self._tcl_lock.acquire() + def loadtk(self): # We want to guard against calling Tk_Init() multiple times err = tklib.Tcl_Eval(self.interp, "info exists tk_version") @@ -159,22 +191,25 @@ flags=tklib.TCL_LEAVE_ERR_MSG if global_only: flags |= tklib.TCL_GLOBAL_ONLY - res = tklib.Tcl_GetVar2Ex(self.interp, name1, name2, flags) - if not res: - self.raiseTclError() - assert self._wantobjects - return FromObj(self, res) + with self._tcl_lock: + res = tklib.Tcl_GetVar2Ex(self.interp, name1, name2, flags) + if not res: + self.raiseTclError() + assert self._wantobjects + return FromObj(self, res) def _setvar(self, name1, value, global_only=False): name1 = varname_converter(name1) + # XXX Acquire tcl lock??? newval = AsObj(value) flags=tklib.TCL_LEAVE_ERR_MSG if global_only: flags |= tklib.TCL_GLOBAL_ONLY - res = tklib.Tcl_SetVar2Ex(self.interp, name1, tkffi.NULL, - newval, flags) - if not res: - self.raiseTclError() + with self._tcl_lock: + res = tklib.Tcl_SetVar2Ex(self.interp, name1, tkffi.NULL, + newval, flags) + if not res: + self.raiseTclError() def _unsetvar(self, name1, name2=None, global_only=False): name1 = varname_converter(name1) @@ -183,9 +218,10 @@ flags=tklib.TCL_LEAVE_ERR_MSG if global_only: flags |= tklib.TCL_GLOBAL_ONLY - res = tklib.Tcl_UnsetVar2(self.interp, name1, name2, flags) - if res == tklib.TCL_ERROR: - self.raiseTclError() + with self._tcl_lock: + res = tklib.Tcl_UnsetVar2(self.interp, name1, name2, flags) + if res == tklib.TCL_ERROR: + self.raiseTclError() def getvar(self, name1, name2=None): return self._var_invoke(self._getvar, name1, name2) @@ -219,9 +255,10 @@ if self.threaded and self.thread_id != tklib.Tcl_GetCurrentThread(): raise NotImplementedError("Call from another thread") - res = tklib.Tcl_CreateCommand( - self.interp, cmdName, _CommandData.PythonCmd, - clientData, _CommandData.PythonCmdDelete) + with self._tcl_lock: + res = tklib.Tcl_CreateCommand( + self.interp, cmdName, _CommandData.PythonCmd, + clientData, _CommandData.PythonCmdDelete) if not res: raise TclError("can't create Tcl command") @@ -229,7 +266,8 @@ if self.threaded and self.thread_id != tklib.Tcl_GetCurrentThread(): raise NotImplementedError("Call from another thread") - res = tklib.Tcl_DeleteCommand(self.interp, cmdName) + with self._tcl_lock: + res = tklib.Tcl_DeleteCommand(self.interp, cmdName) if res == -1: raise TclError("can't delete Tcl command") @@ -256,11 +294,12 @@ tklib.Tcl_IncrRefCount(obj) objects[i] = obj - res = tklib.Tcl_EvalObjv(self.interp, argc, objects, flags) - if res == tklib.TCL_ERROR: - self.raiseTclError() - else: - result = self._callResult() + with self._tcl_lock: + res = tklib.Tcl_EvalObjv(self.interp, argc, objects, flags) + if res == tklib.TCL_ERROR: + self.raiseTclError() + else: + result = self._callResult() finally: for obj in objects: if obj: @@ -280,17 +319,19 @@ def eval(self, script): self._check_tcl_appartment() - res = tklib.Tcl_Eval(self.interp, script) - if res == tklib.TCL_ERROR: - self.raiseTclError() - return tkffi.string(tklib.Tcl_GetStringResult(self.interp)) + with self._tcl_lock: + res = tklib.Tcl_Eval(self.interp, script) + if res == tklib.TCL_ERROR: + self.raiseTclError() + return tkffi.string(tklib.Tcl_GetStringResult(self.interp)) def evalfile(self, filename): self._check_tcl_appartment() - res = tklib.Tcl_EvalFile(self.interp, filename) - if res == tklib.TCL_ERROR: - self.raiseTclError() - return tkffi.string(tklib.Tcl_GetStringResult(self.interp)) + with self._tcl_lock: + res = tklib.Tcl_EvalFile(self.interp, filename) + if res == tklib.TCL_ERROR: + self.raiseTclError() + return tkffi.string(tklib.Tcl_GetStringResult(self.interp)) def split(self, arg): if isinstance(arg, tuple): @@ -375,7 +416,10 @@ if self.threaded: result = tklib.Tcl_DoOneEvent(0) else: - raise NotImplementedError("TCL configured without threads") + with self._tcl_lock: + result = tklib.Tcl_DoOneEvent(tklib.TCL_DONT_WAIT) + if result == 0: + time.sleep(self._busywaitinterval) if result < 0: break diff --git a/lib_pypy/_tkinter/tklib.py b/lib_pypy/_tkinter/tklib.py --- a/lib_pypy/_tkinter/tklib.py +++ b/lib_pypy/_tkinter/tklib.py @@ -1,6 +1,7 @@ # C bindings with libtcl and libtk. from cffi import FFI +import sys tkffi = FFI() @@ -18,6 +19,8 @@ #define TCL_EVAL_DIRECT ... #define TCL_EVAL_GLOBAL ... +#define TCL_DONT_WAIT ... + typedef unsigned short Tcl_UniChar; typedef ... Tcl_Interp; typedef ...* Tcl_ThreadId; @@ -102,6 +105,17 @@ int Tk_GetNumMainWindows(); """) +# XXX find a better way to detect paths +# XXX pick up CPPFLAGS and LDFLAGS and add to these paths? +if sys.platform.startswith("openbsd"): + incdirs = ['/usr/local/include/tcl8.5', '/usr/local/include/tk8.5', '/usr/X11R6/include'] + linklibs = ['tk85', 'tcl85'] + libdirs = ['/usr/local/lib', '/usr/X11R6/lib'] +else: + incdirs=['/usr/include/tcl'] + linklibs=['tcl', 'tk'] + libdirs = [] + tklib = tkffi.verify(""" #include #include @@ -109,6 +123,7 @@ char *get_tk_version() { return TK_VERSION; } char *get_tcl_version() { return TCL_VERSION; } """, -include_dirs=['/usr/include/tcl'], -libraries=['tcl', 'tk'], +include_dirs=incdirs, +libraries=linklibs, +library_dirs = libdirs ) diff --git a/lib_pypy/cffi/__init__.py b/lib_pypy/cffi/__init__.py --- a/lib_pypy/cffi/__init__.py +++ b/lib_pypy/cffi/__init__.py @@ -4,5 +4,5 @@ from .api import FFI, CDefError, FFIError from .ffiplatform import VerificationError, VerificationMissing -__version__ = "0.7" -__version_info__ = (0, 7) +__version__ = "0.7.2" +__version_info__ = (0, 7, 2) diff --git a/lib_pypy/cffi/api.py b/lib_pypy/cffi/api.py --- a/lib_pypy/cffi/api.py +++ b/lib_pypy/cffi/api.py @@ -54,7 +54,8 @@ # _cffi_backend.so compiled. import _cffi_backend as backend from . import __version__ - assert backend.__version__ == __version__ + assert (backend.__version__ == __version__ or + backend.__version__ == __version__[:3]) # (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.) diff --git a/lib_pypy/cffi/commontypes.py b/lib_pypy/cffi/commontypes.py --- a/lib_pypy/cffi/commontypes.py +++ b/lib_pypy/cffi/commontypes.py @@ -30,7 +30,9 @@ elif result in model.PrimitiveType.ALL_PRIMITIVE_TYPES: result = model.PrimitiveType(result) else: - assert commontype != result + if commontype == result: + raise api.FFIError("Unsupported type: %r. Please file a bug " + "if you think it should be." % (commontype,)) result = resolve_common_type(result) # recursively assert isinstance(result, model.BaseTypeByIdentity) _CACHE[commontype] = result diff --git a/lib_pypy/cffi/cparser.py b/lib_pypy/cffi/cparser.py --- a/lib_pypy/cffi/cparser.py +++ b/lib_pypy/cffi/cparser.py @@ -290,13 +290,26 @@ # assume a primitive type. get it from .names, but reduce # synonyms to a single chosen combination names = list(type.names) - if names == ['signed'] or names == ['unsigned']: - names.append('int') - if names[0] == 'signed' and names != ['signed', 'char']: - names.pop(0) - if (len(names) > 1 and names[-1] == 'int' - and names != ['unsigned', 'int']): - names.pop() + if names != ['signed', 'char']: # keep this unmodified + prefixes = {} + while names: + name = names[0] + if name in ('short', 'long', 'signed', 'unsigned'): + prefixes[name] = prefixes.get(name, 0) + 1 + del names[0] + else: + break + # ignore the 'signed' prefix below, and reorder the others + newnames = [] + for prefix in ('unsigned', 'short', 'long'): + for i in range(prefixes.get(prefix, 0)): + newnames.append(prefix) + if not names: + names = ['int'] # implicitly + if names == ['int']: # but kill it if 'short' or 'long' + if 'short' in prefixes or 'long' in prefixes: + names = [] + names = newnames + names ident = ' '.join(names) if ident == 'void': return model.void_type @@ -500,8 +513,8 @@ self._partial_length = True return None # - raise api.FFIError("unsupported non-constant or " - "not immediately constant expression") + raise api.FFIError("unsupported expression: expected a " + "simple numeric constant") def _build_enum_type(self, explicit_name, decls): if decls is not None: diff --git a/lib_pypy/cffi/vengine_gen.py b/lib_pypy/cffi/vengine_gen.py --- a/lib_pypy/cffi/vengine_gen.py +++ b/lib_pypy/cffi/vengine_gen.py @@ -61,7 +61,9 @@ def load_library(self): # import it with the CFFI backend backend = self.ffi._backend - module = backend.load_library(self.verifier.modulefilename) + # needs to make a path that contains '/', on Posix + filename = os.path.join(os.curdir, self.verifier.modulefilename) + module = backend.load_library(filename) # # call loading_gen_struct() to get the struct layout inferred by # the C compiler diff --git a/pypy/doc/faq.rst b/pypy/doc/faq.rst --- a/pypy/doc/faq.rst +++ b/pypy/doc/faq.rst @@ -356,7 +356,7 @@ attempt to point newcomers at existing alternatives, which are more mainstream and where they will get help from many people.* - *If anybody seriously wants to promote RPython anyway, he is welcome + *If anybody seriously wants to promote RPython anyway, they are welcome to: we won't actively resist such a plan. There are a lot of things that could be done to make RPython a better Java-ish language for example, starting with supporting non-GIL-based multithreading, but we @@ -396,8 +396,8 @@ patch the generated machine code. So the position of the core PyPy developers is that if anyone wants to -make an N+1'th attempt with LLVM, he is welcome, and he will receive a -bit of help on the IRC channel, but he is left with the burden of proof +make an N+1'th attempt with LLVM, they are welcome, and will be happy to +provide help in the IRC channel, but they are left with the burden of proof that it works. ---------------------- 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 @@ -80,6 +80,9 @@ .. branch: reflex-support .. branch: numpypy-inplace-op .. branch: rewritten-loop-logging +.. branch: no-release-gil +.. branch: safe-win-mmap +.. branch: boolean-indexing-cleanup .. branch: nobold-backtrace Work on improving UnionError messages and stack trace displays. diff --git a/pypy/interpreter/baseobjspace.py b/pypy/interpreter/baseobjspace.py --- a/pypy/interpreter/baseobjspace.py +++ b/pypy/interpreter/baseobjspace.py @@ -77,12 +77,12 @@ raise NotImplementedError("only for interp-level user subclasses " "from typedef.py") - def getname(self, space, default='?'): + def getname(self, space): try: return space.str_w(space.getattr(self, space.wrap('__name__'))) except OperationError, e: if e.match(space, space.w_TypeError) or e.match(space, space.w_AttributeError): - return default + return '?' raise def getaddrstring(self, space): diff --git a/pypy/interpreter/function.py b/pypy/interpreter/function.py --- a/pypy/interpreter/function.py +++ b/pypy/interpreter/function.py @@ -482,17 +482,16 @@ space.abstract_isinstance_w(w_firstarg, self.w_class)): pass # ok else: - clsdescr = self.w_class.getname(space, "") - if clsdescr: + clsdescr = self.w_class.getname(space) + if clsdescr and clsdescr != '?': clsdescr += " instance" else: clsdescr = "instance" if w_firstarg is None: instdescr = "nothing" else: - instname = space.abstract_getclass(w_firstarg).getname(space, - "") - if instname: + instname = space.abstract_getclass(w_firstarg).getname(space) + if instname and instname != '?': instdescr = instname + " instance" else: instdescr = "instance" diff --git a/pypy/interpreter/test/test_argument.py b/pypy/interpreter/test/test_argument.py --- a/pypy/interpreter/test/test_argument.py +++ b/pypy/interpreter/test/test_argument.py @@ -128,7 +128,7 @@ def type(self, obj): class Type: - def getname(self, space, default='?'): + def getname(self, space): return type(obj).__name__ return Type() diff --git a/pypy/module/__pypy__/interp_time.py b/pypy/module/__pypy__/interp_time.py --- a/pypy/module/__pypy__/interp_time.py +++ b/pypy/module/__pypy__/interp_time.py @@ -48,11 +48,11 @@ c_clock_gettime = rffi.llexternal("clock_gettime", [lltype.Signed, lltype.Ptr(TIMESPEC)], rffi.INT, - compilation_info=CConfig._compilation_info_, threadsafe=False + compilation_info=CConfig._compilation_info_, releasegil=False ) c_clock_getres = rffi.llexternal("clock_getres", [lltype.Signed, lltype.Ptr(TIMESPEC)], rffi.INT, - compilation_info=CConfig._compilation_info_, threadsafe=False + compilation_info=CConfig._compilation_info_, releasegil=False ) @unwrap_spec(clk_id="c_int") diff --git a/pypy/module/_cffi_backend/ccallback.py b/pypy/module/_cffi_backend/ccallback.py --- a/pypy/module/_cffi_backend/ccallback.py +++ b/pypy/module/_cffi_backend/ccallback.py @@ -54,6 +54,13 @@ if rffi.cast(lltype.Signed, res) != clibffi.FFI_OK: raise OperationError(space.w_SystemError, space.wrap("libffi failed to build this callback")) + # + # We must setup the GIL here, in case the callback is invoked in + # some other non-Pythonic thread. This is the same as cffi on + # CPython. + if space.config.translation.thread: + from pypy.module.thread.os_thread import setup_threads + setup_threads(space) def get_closure(self): return rffi.cast(clibffi.FFI_CLOSUREP, self._cdata) 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 @@ -26,6 +26,9 @@ def try_ldflags(): yield ExternalCompilationInfo(libraries=['curses']) yield ExternalCompilationInfo(libraries=['curses', 'tinfo']) + yield ExternalCompilationInfo(libraries=['ncurses']) + yield ExternalCompilationInfo(libraries=['ncurses'], + library_dirs=['/usr/lib64']) def try_tools(): try: 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 @@ -28,7 +28,7 @@ 'CreateSemaphoreA', [rffi.VOIDP, rffi.LONG, rffi.LONG, rwin32.LPCSTR], rwin32.HANDLE) _CloseHandle = rwin32.winexternal('CloseHandle', [rwin32.HANDLE], - rwin32.BOOL, threadsafe=False) + rwin32.BOOL, releasegil=False) _ReleaseSemaphore = rwin32.winexternal( 'ReleaseSemaphore', [rwin32.HANDLE, rffi.LONG, rffi.LONGP], rwin32.BOOL) @@ -82,8 +82,8 @@ _sem_open = external('sem_open', [rffi.CCHARP, rffi.INT, rffi.INT, rffi.UINT], SEM_T) - # tread sem_close as not threadsafe for now to be able to use the __del__ - _sem_close = external('sem_close', [SEM_T], rffi.INT, threadsafe=False) + # sem_close is releasegil=False to be able to use it in the __del__ + _sem_close = external('sem_close', [SEM_T], rffi.INT, releasegil=False) _sem_unlink = external('sem_unlink', [rffi.CCHARP], rffi.INT) _sem_wait = external('sem_wait', [SEM_T], rffi.INT) _sem_trywait = external('sem_trywait', [SEM_T], rffi.INT) diff --git a/pypy/module/_pypyjson/test/test__pypyjson.py b/pypy/module/_pypyjson/test/test__pypyjson.py --- a/pypy/module/_pypyjson/test/test__pypyjson.py +++ b/pypy/module/_pypyjson/test/test__pypyjson.py @@ -1,5 +1,5 @@ # -*- encoding: utf-8 -*- -import py +import py, sys from pypy.module._pypyjson.interp_decoder import JSONDecoder def test_skip_whitespace(): @@ -16,6 +16,9 @@ class AppTest(object): spaceconfig = {"objspace.usemodules._pypyjson": True} + def setup_class(cls): + cls.w_run_on_16bit = cls.space.wrap(sys.maxunicode == 65535) + def test_raise_on_unicode(self): import _pypyjson raises(TypeError, _pypyjson.loads, u"42") @@ -178,11 +181,11 @@ raises(ValueError, "_pypyjson.loads('[1: 2]')") raises(ValueError, "_pypyjson.loads('[1, 2')") raises(ValueError, """_pypyjson.loads('["extra comma",]')""") - + def test_unicode_surrogate_pair(self): + if self.run_on_16bit: + skip("XXX fix me or mark definitely skipped") import _pypyjson expected = u'z\U0001d120x' res = _pypyjson.loads('"z\\ud834\\udd20x"') assert res == expected - - 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 @@ -175,8 +175,8 @@ state = '; dead' else: typename = space.type(w_obj).getname(space) - objname = w_obj.getname(space, '') - if objname: + objname = w_obj.getname(space) + if objname and objname != '?': state = "; to '%s' (%s)" % (typename, objname) else: state = "; to '%s'" % (typename,) 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 @@ -144,12 +144,12 @@ BZ2_bzCompressInit = external('BZ2_bzCompressInit', [bz_stream, rffi.INT, rffi.INT, rffi.INT], rffi.INT) BZ2_bzCompressEnd = external('BZ2_bzCompressEnd', [bz_stream], rffi.INT, - threadsafe=False) + releasegil=False) BZ2_bzCompress = external('BZ2_bzCompress', [bz_stream, rffi.INT], rffi.INT) BZ2_bzDecompressInit = external('BZ2_bzDecompressInit', [bz_stream, rffi.INT, rffi.INT], rffi.INT) BZ2_bzDecompressEnd = external('BZ2_bzDecompressEnd', [bz_stream], rffi.INT, - threadsafe=False) + releasegil=False) BZ2_bzDecompress = external('BZ2_bzDecompress', [bz_stream], rffi.INT) def _catch_bz2_error(space, bzerror): diff --git a/pypy/module/cppyy/capi/builtin_capi.py b/pypy/module/cppyy/capi/builtin_capi.py --- a/pypy/module/cppyy/capi/builtin_capi.py +++ b/pypy/module/cppyy/capi/builtin_capi.py @@ -27,7 +27,7 @@ _c_num_scopes = rffi.llexternal( "cppyy_num_scopes", [C_SCOPE], rffi.INT, - threadsafe=ts_reflect, + releasegil=ts_reflect, compilation_info=backend.eci) def c_num_scopes(space, cppscope): return _c_num_scopes(cppscope.handle) @@ -41,28 +41,28 @@ _c_resolve_name = rffi.llexternal( "cppyy_resolve_name", [rffi.CCHARP], rffi.CCHARP, - threadsafe=ts_reflect, + releasegil=ts_reflect, compilation_info=backend.eci) def c_resolve_name(space, name): return charp2str_free(space, _c_resolve_name(name)) _c_get_scope_opaque = rffi.llexternal( "cppyy_get_scope", [rffi.CCHARP], C_SCOPE, - threadsafe=ts_reflect, + releasegil=ts_reflect, compilation_info=backend.eci) def c_get_scope_opaque(space, name): return _c_get_scope_opaque(name) _c_get_template = rffi.llexternal( "cppyy_get_template", [rffi.CCHARP], C_TYPE, - threadsafe=ts_reflect, + releasegil=ts_reflect, compilation_info=backend.eci) def c_get_template(space, name): return _c_get_template(name) _c_actual_class = rffi.llexternal( "cppyy_actual_class", [C_TYPE, C_OBJECT], C_TYPE, - threadsafe=ts_reflect, + releasegil=ts_reflect, compilation_info=backend.eci) def c_actual_class(space, cppclass, cppobj): return _c_actual_class(cppclass.handle, cppobj) @@ -71,21 +71,21 @@ _c_allocate = rffi.llexternal( "cppyy_allocate", [C_TYPE], C_OBJECT, - threadsafe=ts_memory, + releasegil=ts_memory, compilation_info=backend.eci) def c_allocate(space, cppclass): return _c_allocate(cppclass.handle) _c_deallocate = rffi.llexternal( "cppyy_deallocate", [C_TYPE, C_OBJECT], lltype.Void, - threadsafe=ts_memory, + releasegil=ts_memory, compilation_info=backend.eci) def c_deallocate(space, cppclass, cppobject): _c_deallocate(cppclass.handle, cppobject) _c_destruct = rffi.llexternal( "cppyy_destruct", [C_TYPE, C_OBJECT], lltype.Void, - threadsafe=ts_call, + releasegil=ts_call, compilation_info=backend.eci) def c_destruct(space, cppclass, cppobject): _c_destruct(cppclass.handle, cppobject) @@ -94,63 +94,63 @@ _c_call_v = rffi.llexternal( "cppyy_call_v", [C_METHOD, C_OBJECT, rffi.INT, rffi.VOIDP], lltype.Void, - threadsafe=ts_call, + releasegil=ts_call, compilation_info=backend.eci) def c_call_v(space, cppmethod, cppobject, nargs, args): _c_call_v(cppmethod, cppobject, nargs, args) _c_call_b = rffi.llexternal( "cppyy_call_b", [C_METHOD, C_OBJECT, rffi.INT, rffi.VOIDP], rffi.UCHAR, - threadsafe=ts_call, + releasegil=ts_call, compilation_info=backend.eci) def c_call_b(space, cppmethod, cppobject, nargs, args): return _c_call_b(cppmethod, cppobject, nargs, args) _c_call_c = rffi.llexternal( "cppyy_call_c", [C_METHOD, C_OBJECT, rffi.INT, rffi.VOIDP], rffi.CHAR, - threadsafe=ts_call, + releasegil=ts_call, compilation_info=backend.eci) def c_call_c(space, cppmethod, cppobject, nargs, args): return _c_call_c(cppmethod, cppobject, nargs, args) _c_call_h = rffi.llexternal( "cppyy_call_h", [C_METHOD, C_OBJECT, rffi.INT, rffi.VOIDP], rffi.SHORT, - threadsafe=ts_call, + releasegil=ts_call, compilation_info=backend.eci) def c_call_h(space, cppmethod, cppobject, nargs, args): return _c_call_h(cppmethod, cppobject, nargs, args) _c_call_i = rffi.llexternal( "cppyy_call_i", [C_METHOD, C_OBJECT, rffi.INT, rffi.VOIDP], rffi.INT, - threadsafe=ts_call, + releasegil=ts_call, compilation_info=backend.eci) def c_call_i(space, cppmethod, cppobject, nargs, args): return _c_call_i(cppmethod, cppobject, nargs, args) _c_call_l = rffi.llexternal( "cppyy_call_l", [C_METHOD, C_OBJECT, rffi.INT, rffi.VOIDP], rffi.LONG, - threadsafe=ts_call, + releasegil=ts_call, compilation_info=backend.eci) def c_call_l(space, cppmethod, cppobject, nargs, args): return _c_call_l(cppmethod, cppobject, nargs, args) _c_call_ll = rffi.llexternal( "cppyy_call_ll", [C_METHOD, C_OBJECT, rffi.INT, rffi.VOIDP], rffi.LONGLONG, - threadsafe=ts_call, + releasegil=ts_call, compilation_info=backend.eci) def c_call_ll(space, cppmethod, cppobject, nargs, args): return _c_call_ll(cppmethod, cppobject, nargs, args) _c_call_f = rffi.llexternal( "cppyy_call_f", [C_METHOD, C_OBJECT, rffi.INT, rffi.VOIDP], rffi.FLOAT, - threadsafe=ts_call, + releasegil=ts_call, compilation_info=backend.eci) def c_call_f(space, cppmethod, cppobject, nargs, args): return _c_call_f(cppmethod, cppobject, nargs, args) _c_call_d = rffi.llexternal( "cppyy_call_d", [C_METHOD, C_OBJECT, rffi.INT, rffi.VOIDP], rffi.DOUBLE, - threadsafe=ts_call, + releasegil=ts_call, compilation_info=backend.eci) def c_call_d(space, cppmethod, cppobject, nargs, args): return _c_call_d(cppmethod, cppobject, nargs, args) @@ -158,14 +158,14 @@ _c_call_r = rffi.llexternal( "cppyy_call_r", [C_METHOD, C_OBJECT, rffi.INT, rffi.VOIDP], rffi.VOIDP, - threadsafe=ts_call, + releasegil=ts_call, compilation_info=backend.eci) def c_call_r(space, cppmethod, cppobject, nargs, args): return _c_call_r(cppmethod, cppobject, nargs, args) _c_call_s = rffi.llexternal( "cppyy_call_s", [C_METHOD, C_OBJECT, rffi.INT, rffi.VOIDP], rffi.CCHARP, - threadsafe=ts_call, + releasegil=ts_call, compilation_info=backend.eci) def c_call_s(space, cppmethod, cppobject, nargs, args): return _c_call_s(cppmethod, cppobject, nargs, args) @@ -173,14 +173,14 @@ _c_constructor = rffi.llexternal( "cppyy_constructor", [C_METHOD, C_TYPE, rffi.INT, rffi.VOIDP], C_OBJECT, - threadsafe=ts_call, + releasegil=ts_call, compilation_info=backend.eci) def c_constructor(space, cppmethod, cppobject, nargs, args): return _c_constructor(cppmethod, cppobject, nargs, args) _c_call_o = rffi.llexternal( "cppyy_call_o", [C_METHOD, C_OBJECT, rffi.INT, rffi.VOIDP, C_TYPE], rffi.LONG, - threadsafe=ts_call, + releasegil=ts_call, compilation_info=backend.eci) def c_call_o(space, method, cppobj, nargs, args, cppclass): return _c_call_o(method, cppobj, nargs, args, cppclass.handle) @@ -188,7 +188,7 @@ _c_get_methptr_getter = rffi.llexternal( "cppyy_get_methptr_getter", [C_SCOPE, C_INDEX], C_METHPTRGETTER_PTR, - threadsafe=ts_reflect, + releasegil=ts_reflect, compilation_info=backend.eci, elidable_function=True) def c_get_methptr_getter(space, cppscope, index): @@ -198,21 +198,21 @@ _c_allocate_function_args = rffi.llexternal( "cppyy_allocate_function_args", [rffi.SIZE_T], rffi.VOIDP, - threadsafe=ts_memory, + releasegil=ts_memory, compilation_info=backend.eci) def c_allocate_function_args(space, size): return _c_allocate_function_args(size) _c_deallocate_function_args = rffi.llexternal( "cppyy_deallocate_function_args", [rffi.VOIDP], lltype.Void, - threadsafe=ts_memory, + releasegil=ts_memory, compilation_info=backend.eci) def c_deallocate_function_args(space, args): _c_deallocate_function_args(args) _c_function_arg_sizeof = rffi.llexternal( "cppyy_function_arg_sizeof", [], rffi.SIZE_T, - threadsafe=ts_memory, + releasegil=ts_memory, compilation_info=backend.eci, elidable_function=True) def c_function_arg_sizeof(space): @@ -220,7 +220,7 @@ _c_function_arg_typeoffset = rffi.llexternal( "cppyy_function_arg_typeoffset", [], rffi.SIZE_T, - threadsafe=ts_memory, + releasegil=ts_memory, compilation_info=backend.eci, elidable_function=True) def c_function_arg_typeoffset(space): @@ -230,14 +230,14 @@ _c_is_namespace = rffi.llexternal( "cppyy_is_namespace", [C_SCOPE], rffi.INT, - threadsafe=ts_reflect, + releasegil=ts_reflect, compilation_info=backend.eci) def c_is_namespace(space, scope): return _c_is_namespace(scope) _c_is_enum = rffi.llexternal( "cppyy_is_enum", [rffi.CCHARP], rffi.INT, - threadsafe=ts_reflect, + releasegil=ts_reflect, compilation_info=backend.eci) def c_is_enum(space, name): return _c_is_enum(name) @@ -246,42 +246,42 @@ _c_final_name = rffi.llexternal( "cppyy_final_name", [C_TYPE], rffi.CCHARP, - threadsafe=ts_reflect, + releasegil=ts_reflect, compilation_info=backend.eci) def c_final_name(space, cpptype): return charp2str_free(space, _c_final_name(cpptype)) _c_scoped_final_name = rffi.llexternal( "cppyy_scoped_final_name", [C_TYPE], rffi.CCHARP, - threadsafe=ts_reflect, + releasegil=ts_reflect, compilation_info=backend.eci) def c_scoped_final_name(space, cpptype): return charp2str_free(space, _c_scoped_final_name(cpptype)) _c_has_complex_hierarchy = rffi.llexternal( "cppyy_has_complex_hierarchy", [C_TYPE], rffi.INT, - threadsafe=ts_reflect, + releasegil=ts_reflect, compilation_info=backend.eci) def c_has_complex_hierarchy(space, cpptype): return _c_has_complex_hierarchy(cpptype) _c_num_bases = rffi.llexternal( "cppyy_num_bases", [C_TYPE], rffi.INT, - threadsafe=ts_reflect, + releasegil=ts_reflect, compilation_info=backend.eci) def c_num_bases(space, cppclass): return _c_num_bases(cppclass.handle) _c_base_name = rffi.llexternal( "cppyy_base_name", [C_TYPE, rffi.INT], rffi.CCHARP, - threadsafe=ts_reflect, + releasegil=ts_reflect, compilation_info=backend.eci) def c_base_name(space, cppclass, base_index): return charp2str_free(space, _c_base_name(cppclass.handle, base_index)) _c_is_subtype = rffi.llexternal( "cppyy_is_subtype", [C_TYPE, C_TYPE], rffi.INT, - threadsafe=ts_reflect, + releasegil=ts_reflect, compilation_info=backend.eci, elidable_function=True) @jit.elidable_promote('2') @@ -293,7 +293,7 @@ _c_base_offset = rffi.llexternal( "cppyy_base_offset", [C_TYPE, C_TYPE, C_OBJECT, rffi.INT], rffi.SIZE_T, - threadsafe=ts_reflect, + releasegil=ts_reflect, compilation_info=backend.eci, elidable_function=True) @jit.elidable_promote('1,2,4') @@ -308,21 +308,21 @@ _c_num_methods = rffi.llexternal( "cppyy_num_methods", [C_SCOPE], rffi.INT, - threadsafe=ts_reflect, + releasegil=ts_reflect, compilation_info=backend.eci) def c_num_methods(space, cppscope): return _c_num_methods(cppscope.handle) _c_method_index_at = rffi.llexternal( "cppyy_method_index_at", [C_SCOPE, rffi.INT], C_INDEX, - threadsafe=ts_reflect, + releasegil=ts_reflect, compilation_info=backend.eci) def c_method_index_at(space, cppscope, imethod): return _c_method_index_at(cppscope.handle, imethod) _c_method_indices_from_name = rffi.llexternal( "cppyy_method_indices_from_name", [C_SCOPE, rffi.CCHARP], C_INDEX_ARRAY, - threadsafe=ts_reflect, + releasegil=ts_reflect, compilation_info=backend.eci) def c_method_indices_from_name(space, cppscope, name): indices = _c_method_indices_from_name(cppscope.handle, name) @@ -341,49 +341,49 @@ _c_method_name = rffi.llexternal( "cppyy_method_name", [C_SCOPE, C_INDEX], rffi.CCHARP, - threadsafe=ts_reflect, + releasegil=ts_reflect, compilation_info=backend.eci) def c_method_name(space, cppscope, index): return charp2str_free(space, _c_method_name(cppscope.handle, index)) _c_method_result_type = rffi.llexternal( "cppyy_method_result_type", [C_SCOPE, C_INDEX], rffi.CCHARP, - threadsafe=ts_reflect, + releasegil=ts_reflect, compilation_info=backend.eci) def c_method_result_type(space, cppscope, index): return charp2str_free(space, _c_method_result_type(cppscope.handle, index)) _c_method_num_args = rffi.llexternal( "cppyy_method_num_args", [C_SCOPE, C_INDEX], rffi.INT, - threadsafe=ts_reflect, + releasegil=ts_reflect, compilation_info=backend.eci) def c_method_num_args(space, cppscope, index): return _c_method_num_args(cppscope.handle, index) _c_method_req_args = rffi.llexternal( "cppyy_method_req_args", [C_SCOPE, C_INDEX], rffi.INT, - threadsafe=ts_reflect, + releasegil=ts_reflect, compilation_info=backend.eci) def c_method_req_args(space, cppscope, index): return _c_method_req_args(cppscope.handle, index) _c_method_arg_type = rffi.llexternal( "cppyy_method_arg_type", [C_SCOPE, C_INDEX, rffi.INT], rffi.CCHARP, - threadsafe=ts_reflect, + releasegil=ts_reflect, compilation_info=backend.eci) def c_method_arg_type(space, cppscope, index, arg_index): return charp2str_free(space, _c_method_arg_type(cppscope.handle, index, arg_index)) _c_method_arg_default = rffi.llexternal( "cppyy_method_arg_default", [C_SCOPE, C_INDEX, rffi.INT], rffi.CCHARP, - threadsafe=ts_reflect, + releasegil=ts_reflect, compilation_info=backend.eci) def c_method_arg_default(space, cppscope, index, arg_index): return charp2str_free(space, _c_method_arg_default(cppscope.handle, index, arg_index)) _c_method_signature = rffi.llexternal( "cppyy_method_signature", [C_SCOPE, C_INDEX], rffi.CCHARP, - threadsafe=ts_reflect, + releasegil=ts_reflect, compilation_info=backend.eci) def c_method_signature(space, cppscope, index): return charp2str_free(space, _c_method_signature(cppscope.handle, index)) @@ -391,19 +391,19 @@ _c_method_is_template = rffi.llexternal( "cppyy_method_is_template", [C_SCOPE, C_INDEX], rffi.INT, - threadsafe=ts_reflect, + releasegil=ts_reflect, compilation_info=backend.eci) def c_method_is_template(space, 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, + releasegil=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, + releasegil=ts_reflect, compilation_info=backend.eci) def c_template_args(space, cppscope, index): nargs = _c_method_num_template_args(cppscope.handle, index) @@ -415,14 +415,14 @@ _c_get_method = rffi.llexternal( "cppyy_get_method", [C_SCOPE, C_INDEX], C_METHOD, - threadsafe=ts_reflect, + releasegil=ts_reflect, compilation_info=backend.eci) def c_get_method(space, cppscope, index): return _c_get_method(cppscope.handle, index) _c_get_global_operator = rffi.llexternal( "cppyy_get_global_operator", [C_SCOPE, C_SCOPE, C_SCOPE, rffi.CCHARP], WLAVC_INDEX, - threadsafe=ts_reflect, + releasegil=ts_reflect, compilation_info=backend.eci) def c_get_global_operator(space, nss, lc, rc, op): if nss is not None: @@ -433,14 +433,14 @@ _c_is_constructor = rffi.llexternal( "cppyy_is_constructor", [C_TYPE, C_INDEX], rffi.INT, - threadsafe=ts_reflect, + releasegil=ts_reflect, compilation_info=backend.eci) def c_is_constructor(space, cppclass, index): return _c_is_constructor(cppclass.handle, index) _c_is_staticmethod = rffi.llexternal( "cppyy_is_staticmethod", [C_TYPE, C_INDEX], rffi.INT, - threadsafe=ts_reflect, + releasegil=ts_reflect, compilation_info=backend.eci) def c_is_staticmethod(space, cppclass, index): return _c_is_staticmethod(cppclass.handle, index) @@ -449,28 +449,28 @@ _c_num_datamembers = rffi.llexternal( "cppyy_num_datamembers", [C_SCOPE], rffi.INT, - threadsafe=ts_reflect, + releasegil=ts_reflect, compilation_info=backend.eci) def c_num_datamembers(space, cppscope): return _c_num_datamembers(cppscope.handle) _c_datamember_name = rffi.llexternal( "cppyy_datamember_name", [C_SCOPE, rffi.INT], rffi.CCHARP, - threadsafe=ts_reflect, + releasegil=ts_reflect, compilation_info=backend.eci) def c_datamember_name(space, cppscope, datamember_index): return charp2str_free(space, _c_datamember_name(cppscope.handle, datamember_index)) _c_datamember_type = rffi.llexternal( "cppyy_datamember_type", [C_SCOPE, rffi.INT], rffi.CCHARP, - threadsafe=ts_reflect, + releasegil=ts_reflect, compilation_info=backend.eci) def c_datamember_type(space, cppscope, datamember_index): return charp2str_free(space, _c_datamember_type(cppscope.handle, datamember_index)) _c_datamember_offset = rffi.llexternal( "cppyy_datamember_offset", [C_SCOPE, rffi.INT], rffi.SIZE_T, - threadsafe=ts_reflect, + releasegil=ts_reflect, compilation_info=backend.eci) def c_datamember_offset(space, cppscope, datamember_index): return _c_datamember_offset(cppscope.handle, datamember_index) @@ -478,7 +478,7 @@ _c_datamember_index = rffi.llexternal( "cppyy_datamember_index", [C_SCOPE, rffi.CCHARP], rffi.INT, - threadsafe=ts_reflect, + releasegil=ts_reflect, compilation_info=backend.eci) def c_datamember_index(space, cppscope, name): return _c_datamember_index(cppscope.handle, name) @@ -487,14 +487,14 @@ _c_is_publicdata = rffi.llexternal( "cppyy_is_publicdata", [C_SCOPE, rffi.INT], rffi.INT, - threadsafe=ts_reflect, + releasegil=ts_reflect, compilation_info=backend.eci) def c_is_publicdata(space, cppscope, datamember_index): return _c_is_publicdata(cppscope.handle, datamember_index) _c_is_staticdata = rffi.llexternal( "cppyy_is_staticdata", [C_SCOPE, rffi.INT], rffi.INT, - threadsafe=ts_reflect, + releasegil=ts_reflect, compilation_info=backend.eci) def c_is_staticdata(space, cppscope, datamember_index): return _c_is_staticdata(cppscope.handle, datamember_index) @@ -503,21 +503,21 @@ _c_strtoll = rffi.llexternal( "cppyy_strtoll", [rffi.CCHARP], rffi.LONGLONG, - threadsafe=ts_helper, + releasegil=ts_helper, compilation_info=backend.eci) def c_strtoll(space, svalue): return _c_strtoll(svalue) _c_strtoull = rffi.llexternal( "cppyy_strtoull", [rffi.CCHARP], rffi.ULONGLONG, - threadsafe=ts_helper, + releasegil=ts_helper, compilation_info=backend.eci) def c_strtoull(space, svalue): return _c_strtoull(svalue) c_free = rffi.llexternal( "cppyy_free", [rffi.VOIDP], lltype.Void, - threadsafe=ts_memory, + releasegil=ts_memory, compilation_info=backend.eci) def charp2str_free(space, charp): @@ -529,7 +529,7 @@ _c_charp2stdstring = rffi.llexternal( "cppyy_charp2stdstring", [rffi.CCHARP], C_OBJECT, - threadsafe=ts_helper, + releasegil=ts_helper, compilation_info=backend.eci) def c_charp2stdstring(space, svalue): charp = rffi.str2charp(svalue) @@ -539,14 +539,14 @@ _c_stdstring2stdstring = rffi.llexternal( "cppyy_stdstring2stdstring", [C_OBJECT], C_OBJECT, - threadsafe=ts_helper, + releasegil=ts_helper, compilation_info=backend.eci) def c_stdstring2stdstring(space, cppobject): return _c_stdstring2stdstring(cppobject) _c_assign2stdstring = rffi.llexternal( "cppyy_assign2stdstring", [C_OBJECT, rffi.CCHARP], lltype.Void, - threadsafe=ts_helper, + releasegil=ts_helper, compilation_info=backend.eci) def c_assign2stdstring(space, cppobject, svalue): charp = rffi.str2charp(svalue) @@ -555,7 +555,7 @@ _c_free_stdstring = rffi.llexternal( "cppyy_free_stdstring", [C_OBJECT], lltype.Void, - threadsafe=ts_helper, + releasegil=ts_helper, compilation_info=backend.eci) def c_free_stdstring(space, cppobject): _c_free_stdstring(cppobject) 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 @@ -60,7 +60,7 @@ _c_load_dictionary = rffi.llexternal( "cppyy_load_dictionary", [rffi.CCHARP], rdynload.DLLHANDLE, - threadsafe=False, + releasegil=False, compilation_info=eci) def c_load_dictionary(name): @@ -84,7 +84,7 @@ _ttree_Branch = rffi.llexternal( "cppyy_ttree_Branch", [rffi.VOIDP, rffi.CCHARP, rffi.CCHARP, rffi.VOIDP, rffi.INT, rffi.INT], rffi.LONG, - threadsafe=False, + releasegil=False, compilation_info=eci) @unwrap_spec(args_w='args_w') @@ -158,7 +158,7 @@ c_ttree_GetEntry = rffi.llexternal( "cppyy_ttree_GetEntry", [rffi.VOIDP, rffi.LONGLONG], rffi.LONGLONG, - threadsafe=False, + releasegil=False, compilation_info=eci) @unwrap_spec(args_w='args_w') diff --git a/pypy/module/cpyext/pystate.py b/pypy/module/cpyext/pystate.py --- a/pypy/module/cpyext/pystate.py +++ b/pypy/module/cpyext/pystate.py @@ -241,7 +241,6 @@ it is necessary to serialize calls to this function.""" if not space.config.translation.thread: raise NoThreads - rthread.gc_thread_prepare() # PyThreadState_Get will allocate a new execution context, # we need to protect gc and other globals with the GIL. rffi.aroundstate.after() diff --git a/pypy/module/crypt/interp_crypt.py b/pypy/module/crypt/interp_crypt.py --- a/pypy/module/crypt/interp_crypt.py +++ b/pypy/module/crypt/interp_crypt.py @@ -8,7 +8,7 @@ else: eci = ExternalCompilationInfo(libraries=['crypt']) c_crypt = rffi.llexternal('crypt', [rffi.CCHARP, rffi.CCHARP], rffi.CCHARP, - compilation_info=eci, threadsafe=False) + compilation_info=eci, releasegil=False) @unwrap_spec(word=str, salt=str) def crypt(space, word, salt): 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 @@ -316,7 +316,8 @@ self.storage = storage def create_iter(self, shape=None, backward_broadcast=False): - if shape is None or shape == self.get_shape(): + if shape is None or \ + support.product(shape) <= support.product(self.get_shape()): return iter.ConcreteArrayIterator(self) r = calculate_broadcast_strides(self.get_strides(), self.get_backstrides(), @@ -385,7 +386,8 @@ loop.fill(self, box.convert_to(self.dtype)) def create_iter(self, shape=None, backward_broadcast=False): - if shape is not None and shape != self.get_shape(): + if shape is not None and shape != self.get_shape() and \ + support.product(shape) > support.product(self.get_shape()): r = calculate_broadcast_strides(self.get_strides(), self.get_backstrides(), self.get_shape(), shape, 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 @@ -88,28 +88,22 @@ w_res = W_NDimArray.from_shape(space, res_shape, self.get_dtype(), w_instance=self) return loop.getitem_filter(w_res, self, arr) - def setitem_filter(self, space, idx, value): - from pypy.module.micronumpy.interp_boxes import Box - val = value + def setitem_filter(self, space, idx, val): if len(idx.get_shape()) > 1 and idx.get_shape() != self.get_shape(): raise OperationError(space.w_ValueError, space.wrap("boolean index array should have 1 dimension")) if idx.get_size() > self.get_size(): raise OperationError(space.w_ValueError, space.wrap("index out of range for array")) - idx_iter = idx.create_iter(self.get_shape()) - size = loop.count_all_true_iter(idx_iter, self.get_shape(), idx.get_dtype()) - if len(val.get_shape()) > 0 and val.get_shape()[0] > 1 and size > val.get_shape()[0]: + idx_iter = idx.create_iter() + size = loop.count_all_true_iter(idx_iter, idx.get_shape(), idx.get_dtype()) + if size > val.get_size() and val.get_size() > 1: raise OperationError(space.w_ValueError, space.wrap("NumPy boolean array indexing assignment " "cannot assign %d input values to " - "the %d output values where the mask is true" % (val.get_shape()[0],size))) - if val.get_shape() == [1]: - box = val.descr_getitem(space, space.wrap(0)) - assert isinstance(box, Box) - val = W_NDimArray(scalar.Scalar(val.get_dtype(), box)) - elif val.get_shape() == [0]: + "the %d output values where the mask is true" % (val.get_size(), size))) + if val.get_shape() == [0]: val.implementation.dtype = self.implementation.dtype - loop.setitem_filter(self, idx, val) + loop.setitem_filter(self, idx, val, size) def _prepare_array_index(self, space, w_index): if isinstance(w_index, W_NDimArray): 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 @@ -372,11 +372,14 @@ 'index_dtype'], reds = 'auto') -def setitem_filter(arr, index, value): +def setitem_filter(arr, index, value, size): arr_iter = arr.create_iter() - index_iter = index.create_iter(arr.get_shape()) - value_iter = value.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() + value_iter = value.create_iter([size]) index_dtype = index.get_dtype() arr_dtype = arr.get_dtype() while not index_iter.done(): 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 @@ -776,7 +776,13 @@ def test_unicode_boxes(self): from numpypy import unicode_ - assert isinstance(unicode_(3), unicode) + try: + u = unicode_(3) + except NotImplementedError, e: + if e.message.find('not supported yet') >= 0: + skip('unicode box not implemented') + else: + assert isinstance(u, unicode) def test_character_dtype(self): from numpypy import array, character 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 @@ -2355,11 +2355,16 @@ def test_array_indexing_bool_specialcases(self): from numpypy import arange, array a = arange(6) - try: - a[a < 3] = [1, 2] - assert False, "Should not work" - except ValueError: - pass + exc = raises(ValueError,'a[a < 3] = [1, 2]') + assert exc.value[0].find('cannot assign') >= 0 + b = arange(4).reshape(2, 2) + 10 + a[a < 4] = b + assert (a == [10, 11, 12, 13, 4, 5]).all() + b += 10 + c = arange(8).reshape(2, 2, 2) + a[a > 9] = c[:, :, 1] + assert (c[:, :, 1] == [[1, 3], [5, 7]]).all() + assert (a == [1, 3, 5, 7, 4, 5]).all() a = arange(6) a[a > 3] = array([15]) assert (a == [0, 1, 2, 3, 15, 15]).all() 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 @@ -50,6 +50,7 @@ '__concat__' : 'concat', '__contains__' : 'contains', 'sequenceIncludes' : 'contains', + '__index__' : 'index', '__delitem__' : 'delitem', '__div__' : 'div', '__eq__' : 'eq', 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 @@ -190,3 +190,9 @@ 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_index(self): + import operator + assert operator.index(42) == 42 + assert operator.__index__(42) == 42 + raises(TypeError, operator.index, "abc") 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 @@ -356,7 +356,7 @@ XML_ParserCreateNS = expat_external( 'XML_ParserCreateNS', [rffi.CCHARP, rffi.CHAR], XML_Parser) XML_ParserFree = expat_external( - 'XML_ParserFree', [XML_Parser], lltype.Void, threadsafe=False) + 'XML_ParserFree', [XML_Parser], lltype.Void, releasegil=False) XML_SetUserData = expat_external( 'XML_SetUserData', [XML_Parser, rffi.VOIDP], lltype.Void) def XML_GetUserData(parser): 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 @@ -109,7 +109,8 @@ 'posix', '_socket', '_sre', '_lsprof', '_weakref', '__pypy__', 'cStringIO', '_collections', 'struct', 'mmap', 'marshal', '_codecs', 'rctime', 'cppyy', - '_cffi_backend', 'pyexpat', '_continuation', '_io']: + '_cffi_backend', 'pyexpat', '_continuation', '_io', + 'thread']: if modname == 'pypyjit' and 'interp_resop' in rest: return False return True diff --git a/pypy/module/pypyjit/test/test_policy.py b/pypy/module/pypyjit/test/test_policy.py --- a/pypy/module/pypyjit/test/test_policy.py +++ b/pypy/module/pypyjit/test/test_policy.py @@ -45,6 +45,10 @@ from pypy.module._io.interp_bytesio import W_BytesIO assert pypypolicy.look_inside_function(W_BytesIO.seek_w.im_func) +def test_thread(): + from pypy.module.thread.os_lock import Lock + assert pypypolicy.look_inside_function(Lock.descr_lock_acquire.im_func) + def test_pypy_module(): from pypy.module._collections.interp_deque import W_Deque from pypy.module._random.interp_random import W_Random 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 @@ -1,3 +1,4 @@ +import py from pypy.module.pypyjit.test_pypy_c.test_00_model import BaseTestPyPyC @@ -48,3 +49,48 @@ i58 = arraylen_gc(p43, descr=...) jump(..., descr=...) """) + + def test_lock_acquire_release(self): + py.test.skip("test too precise, please fix me") + def main(n): + import threading + lock = threading.Lock() + while n > 0: + with lock: + n -= 1 + log = self.run(main, [500]) + assert log.result == main(500) + loop, = log.loops_by_filename(self.filepath) + assert loop.match(""" + i58 = int_gt(i43, 0) + guard_true(i58, descr=) + p59 = getfield_gc(p15, descr=) + i60 = getfield_gc(p59, descr=) + p61 = force_token() + setfield_gc(p0, p61, descr=) + i62 = call_release_gil(4312440032, i60, 1, descr=) + guard_not_forced(descr=) + guard_no_exception(descr=) + i63 = int_is_true(i62) + guard_true(i63, descr=) + i64 = int_sub(i43, 1) + guard_not_invalidated(descr=) + p66 = getfield_gc(p15, descr=) + i67 = getfield_gc(p66, descr=) + p68 = force_token() + setfield_gc(p0, p68, descr=) + i69 = call_release_gil(4312440032, i67, 0, descr=) + guard_not_forced(descr=) + guard_no_exception(descr=) + i70 = int_is_true(i69) + guard_false(i70, descr=) + i71 = getfield_gc(p66, descr=) + p72 = force_token() + setfield_gc(p0, p72, descr=) + call_release_gil(4312441056, i71, descr=) + guard_not_forced(descr=) + guard_no_exception(descr=) + guard_not_invalidated(descr=) + --TICK-- + jump(..., descr=TargetToken(4361239720)) + """) 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 @@ -151,7 +151,7 @@ return rffi.llexternal(name, args, result, compilation_info=eci, calling_conv=calling_conv, - threadsafe=False) + releasegil=False) if _POSIX: cConfig.timeval.__name__ = "_timeval" diff --git a/pypy/module/test_lib_pypy/cffi_tests/backend_tests.py b/pypy/module/test_lib_pypy/cffi_tests/backend_tests.py --- a/pypy/module/test_lib_pypy/cffi_tests/backend_tests.py +++ b/pypy/module/test_lib_pypy/cffi_tests/backend_tests.py @@ -199,6 +199,9 @@ typerepr = self.TypeRepr ffi = FFI(backend=self.Backend()) ffi.cdef("struct foo { short a, b, c; };") + p = ffi.cast("short unsigned int", 0) + assert repr(p) == "" + assert repr(ffi.typeof(p)) == typerepr % "unsigned short" p = ffi.cast("unsigned short int", 0) assert repr(p) == "" assert repr(ffi.typeof(p)) == typerepr % "unsigned short" @@ -535,13 +538,13 @@ for c_type, expected_size in [ ('char', 1), ('unsigned int', 4), - ('char *', SIZE_OF_LONG), + ('char *', SIZE_OF_PTR), ('int[5]', 20), ('struct foo', 12), ('union foo', 4), ]: size = ffi.sizeof(c_type) - assert size == expected_size + assert size == expected_size, (size, expected_size, ctype) def test_sizeof_cdata(self): ffi = FFI(backend=self.Backend()) diff --git a/pypy/module/test_lib_pypy/cffi_tests/callback_in_thread.py b/pypy/module/test_lib_pypy/cffi_tests/callback_in_thread.py --- a/pypy/module/test_lib_pypy/cffi_tests/callback_in_thread.py +++ b/pypy/module/test_lib_pypy/cffi_tests/callback_in_thread.py @@ -27,6 +27,7 @@ seen = [] @ffi.callback('int(*)(int,int)') def mycallback(x, y): + time.sleep(0.022) seen.append((x, y)) return 0 lib.threaded_ballback_test(mycallback) diff --git a/pypy/module/test_lib_pypy/cffi_tests/test_function.py b/pypy/module/test_lib_pypy/cffi_tests/test_function.py --- a/pypy/module/test_lib_pypy/cffi_tests/test_function.py +++ b/pypy/module/test_lib_pypy/cffi_tests/test_function.py @@ -382,3 +382,26 @@ sin100 = my_decorator(m.sin) x = sin100(1.23) assert x == math.sin(1.23) + 100 + + def test_free_callback_cycle(self): + if self.Backend is CTypesBackend: + py.test.skip("seems to fail with the ctypes backend on windows") + import weakref + def make_callback(data): + container = [data] + callback = ffi.callback('int()', lambda: len(container)) + container.append(callback) + # Ref cycle: callback -> lambda (closure) -> container -> callback + return callback + + class Data(object): + pass + ffi = FFI(backend=self.Backend()) + data = Data() + callback = make_callback(data) + wr = weakref.ref(data) + del callback, data + for i in range(3): + if wr() is not None: + import gc; gc.collect() + assert wr() is None # 'data' does not leak diff --git a/pypy/module/test_lib_pypy/cffi_tests/test_version.py b/pypy/module/test_lib_pypy/cffi_tests/test_version.py --- a/pypy/module/test_lib_pypy/cffi_tests/test_version.py +++ b/pypy/module/test_lib_pypy/cffi_tests/test_version.py @@ -8,6 +8,8 @@ BACKEND_VERSIONS = { '0.4.2': '0.4', # did not change + '0.7.1': '0.7', # did not change + '0.7.2': '0.7', # did not change } def test_version(): @@ -22,7 +24,7 @@ content = open(p).read() # v = cffi.__version__ - assert ("version = '%s'\n" % v) in content + assert ("version = '%s'\n" % BACKEND_VERSIONS.get(v, v)) in content assert ("release = '%s'\n" % v) in content def test_doc_version_file(): @@ -45,4 +47,5 @@ v = cffi.__version__ p = os.path.join(parent, 'c', 'test_c.py') content = open(p).read() - assert ('assert __version__ == "%s"' % v) in content + assert (('assert __version__ == "%s"' % BACKEND_VERSIONS.get(v, v)) + in content) diff --git a/pypy/module/test_lib_pypy/test_curses.py b/pypy/module/test_lib_pypy/test_curses.py --- a/pypy/module/test_lib_pypy/test_curses.py +++ b/pypy/module/test_lib_pypy/test_curses.py @@ -1,4 +1,8 @@ import pytest +import sys +if sys.platform == 'win32': + #This module does not exist in windows + pytest.skip('no curses on windows') # Check that lib_pypy.cffi finds the correct version of _cffi_backend. # Otherwise, the test is skipped. It should never be skipped when run diff --git a/pypy/module/test_lib_pypy/test_resource.py b/pypy/module/test_lib_pypy/test_resource.py --- a/pypy/module/test_lib_pypy/test_resource.py +++ b/pypy/module/test_lib_pypy/test_resource.py @@ -3,6 +3,9 @@ from lib_pypy.ctypes_config_cache import rebuild from pypy.module.test_lib_pypy.support import import_lib_pypy +import os +if os.name != 'posix': + skip('resource.h only available on unix') class AppTestResource: 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 @@ -182,7 +182,6 @@ bootstrapper.acquire(space, w_callable, args) try: try: - rthread.gc_thread_prepare() # (this has no effect any more) ident = rthread.start_new_thread(bootstrapper.bootstrap, ()) except Exception: bootstrapper.release() # normally called by the new thread diff --git a/pypy/module/thread/test/test_gil.py b/pypy/module/thread/test/test_gil.py --- a/pypy/module/thread/test/test_gil.py +++ b/pypy/module/thread/test/test_gil.py @@ -72,7 +72,6 @@ state.datalen4 = 0 state.threadlocals = gil.GILThreadLocals() state.threadlocals.setup_threads(space) - thread.gc_thread_prepare() subident = thread.start_new_thread(bootstrap, ()) mainident = thread.get_ident() runme(True) diff --git a/pypy/module/thread/test/test_thread.py b/pypy/module/thread/test/test_thread.py --- a/pypy/module/thread/test/test_thread.py +++ b/pypy/module/thread/test/test_thread.py @@ -187,9 +187,12 @@ skip("this OS supports too many threads to check (> 1000)") lock = thread.allocate_lock() lock.acquire() + count = [0] def f(): + count[0] += 1 lock.acquire() lock.release() + count[0] -= 1 try: try: for i in range(1000): @@ -197,11 +200,15 @@ finally: lock.release() # wait a bit to allow most threads to finish now - self.busywait(2.0) + while count[0] > 10: + print count[0] # <- releases the GIL + print "ok." except (thread.error, MemoryError): pass else: raise Exception("could unexpectedly start 1000 threads") + # safety: check that we can start a new thread here + thread.start_new_thread(lambda: None, ()) def test_stack_size(self): import thread diff --git a/pypy/objspace/descroperation.py b/pypy/objspace/descroperation.py --- a/pypy/objspace/descroperation.py +++ b/pypy/objspace/descroperation.py @@ -597,8 +597,8 @@ if num1 != num2: lt = num1 # if obj1 is a number, it is Lower Than obj2 else: - name1 = w_typ1.getname(space, "") - name2 = w_typ2.getname(space, "") + name1 = w_typ1.getname(space) + name2 = w_typ2.getname(space) if name1 != name2: lt = name1 < name2 else: 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 @@ -494,6 +494,12 @@ else: return w_self.name + def getname(w_self, space): + name = w_self.name + if name is None: + name = '?' + return name + def add_subclass(w_self, w_subclass): space = w_self.space if not space.config.translation.rweakref: 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 @@ -29,6 +29,7 @@ from rpython.rtyper.annlowlevel import llhelper, cast_instance_to_gcref from rpython.rtyper.lltypesystem import lltype, rffi from rpython.jit.backend.arm import callbuilder +from rpython.rtyper.lltypesystem.lloperation import llop class AssemblerARM(ResOpAssembler): @@ -1488,7 +1489,9 @@ def not_implemented(msg): - os.write(2, '[ARM/asm] %s\n' % msg) + msg = '[ARM/asm] %s\n' % msg + if we_are_translated(): + llop.debug_print(lltype.Void, msg) raise NotImplementedError(msg) 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 @@ -56,13 +56,13 @@ def finish_once(self): self.assembler.finish_once() - def compile_loop(self, logger, inputargs, operations, looptoken, - log=True, name=''): + def compile_loop(self, inputargs, operations, looptoken, + log=True, name='', logger=None): return self.assembler.assemble_loop(logger, name, inputargs, operations, looptoken, log=log) - def compile_bridge(self, logger, faildescr, inputargs, operations, - original_loop_token, log=True): + def compile_bridge(self, faildescr, inputargs, operations, + original_loop_token, log=True, logger=None): clt = original_loop_token.compiled_loop_token clt.compiling_a_bridge() return self.assembler.assemble_bridge(logger, faildescr, inputargs, 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 @@ -40,7 +40,7 @@ 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(None, inputargs, operations, looptoken) + cpu.compile_loop(inputargs, operations, looptoken) args = [-12 , -26 , -19 , 7 , -5 , -24 , -37 , 62 , 9 , 12] deadframe = cpu.execute_token(looptoken, *args) assert cpu.get_int_value(deadframe, 0) == 0 @@ -92,7 +92,7 @@ operations[9].setfailargs([v15, v7, v10, v18, v4, v17, v1]) operations[-1].setfailargs([v7, v1, v2]) looptoken = JitCellToken() - cpu.compile_loop(None, inputargs, operations, looptoken) + cpu.compile_loop(inputargs, operations, looptoken) args = [16 , 5 , 5 , 16 , 46 , 6 , 63 , 39 , 78 , 0] deadframe = cpu.execute_token(looptoken, *args) assert cpu.get_int_value(deadframe, 0) == 105 @@ -136,7 +136,7 @@ operations[-1].setfailargs([v5, v2, v1, v10, v3, v8, v4, v6]) looptoken = JitCellToken() - cpu.compile_loop(None, inputargs, operations, looptoken) + cpu.compile_loop(inputargs, operations, looptoken) args = [-5 , 24 , 46 , -15 , 13 , -8 , 0 , -6 , 6 , 6] deadframe = cpu.execute_token(looptoken, *args) assert cpu.get_latest_descr(deadframe).identifier == 2 @@ -179,7 +179,7 @@ operations[5].setfailargs([]) operations[-1].setfailargs([v8, v2, v6, v5, v7, v1, v10]) looptoken = JitCellToken() - cpu.compile_loop(None, inputargs, operations, looptoken) + cpu.compile_loop(inputargs, operations, looptoken) args = [19 , -3 , -58 , -7 , 12 , 22 , -54 , -29 , -19 , -64] deadframe = cpu.execute_token(looptoken, *args) assert cpu.get_int_value(deadframe, 0) == -29 @@ -223,7 +223,7 @@ looptoken = JitCellToken() operations[5].setfailargs([]) operations[-1].setfailargs([v1, v4, v10, v8, v7, v3]) - cpu.compile_loop(None, inputargs, operations, looptoken) + cpu.compile_loop(inputargs, operations, looptoken) args = [1073741824 , 95 , -16 , 5 , 92 , 12 , 32 , 17 , 37 , -63] deadframe = cpu.execute_token(looptoken, *args) assert cpu.get_int_value(deadframe, 0) == 1073741824 @@ -280,7 +280,7 @@ 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(None, inputargs, operations, looptoken) + cpu.compile_loop(inputargs, operations, looptoken) deadframe = cpu.execute_token(looptoken, *args) assert cpu.get_latest_descr(deadframe).identifier == 3 assert cpu.get_int_value(deadframe, 0) == 12 @@ -328,7 +328,7 @@ operations[8].setfailargs([v5, v9]) operations[-1].setfailargs([v4, v10, v6, v5, v9, v7]) looptoken = JitCellToken() - cpu.compile_loop(None, inputargs, operations, looptoken) + cpu.compile_loop(inputargs, operations, looptoken) args = [-8 , 0 , 62 , 35 , 16 , 9 , 30 , 581610154 , -1 , 738197503] deadframe = cpu.execute_token(looptoken, *args) assert cpu.get_latest_descr(deadframe).identifier == 2 @@ -378,7 +378,7 @@ operations[-2].setfailargs([v9, v4, v10, v11, v14]) operations[-1].setfailargs([v10, v8, v1, v6, v4]) looptoken = JitCellToken() - cpu.compile_loop(None, inputargs, operations, looptoken) + cpu.compile_loop(inputargs, operations, looptoken) args = [-39 , -18 , 1588243114 , -9 , -4 , 1252698794 , 0 , 715827882 , -15 , 536870912] deadframe = cpu.execute_token(looptoken, *args) assert cpu.get_latest_descr(deadframe).identifier == 1 @@ -433,7 +433,7 @@ operations[9].setfailargs([v5, v7, v12, v14, v2, v13, v8]) operations[-1].setfailargs([v1, v2, v9]) looptoken = JitCellToken() - cpu.compile_loop(None, inputargs, operations, looptoken) + cpu.compile_loop(inputargs, operations, looptoken) args = [0 , -2 , 24 , 1 , -4 , 13 , -95 , 33 , 2 , -44] deadframe = cpu.execute_token(looptoken, *args) assert cpu.get_latest_descr(deadframe).identifier == 3 @@ -475,7 +475,7 @@ 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(None, inputargs, operations, looptoken) + cpu.compile_loop(inputargs, operations, looptoken) args = [3 , -5 , 1431655765 , 47 , 12 , 1789569706 , 15 , 939524096 , 16 , -43] deadframe = cpu.execute_token(looptoken, *args) assert cpu.get_latest_descr(deadframe).identifier == 1 @@ -524,7 +524,7 @@ operations[-1].setfailargs([v2, v3, v5, v7, v10, v8, v9]) operations[4].setfailargs([v14]) looptoken = JitCellToken() - cpu.compile_loop(None, inputargs, operations, looptoken) + cpu.compile_loop(inputargs, operations, looptoken) args = [14 , -20 , 18 , -2058005163 , 6 , 1 , -16 , 11 , 0 , 19] deadframe = cpu.execute_token(looptoken, *args) assert cpu.get_latest_descr(deadframe).identifier == 1 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 @@ -24,7 +24,7 @@ cpu = CPU(None, None) cpu.setup_once() looptoken = JitCellToken() - cpu.compile_loop(None, inputargs, operations, looptoken) + cpu.compile_loop(inputargs, operations, looptoken) deadframe = cpu.execute_token(looptoken, 9) assert cpu.get_int_value(deadframe, 0) == (9 >> 3) assert cpu.get_int_value(deadframe, 1) == (~18) @@ -48,7 +48,7 @@ cpu = CPU(None, None) cpu.setup_once() looptoken = JitCellToken() - cpu.compile_loop(None, inputargs, operations, looptoken) + cpu.compile_loop(inputargs, operations, looptoken) deadframe = cpu.execute_token(looptoken, -10) assert cpu.get_int_value(deadframe, 0) == 0 assert cpu.get_int_value(deadframe, 1) == -1000 @@ -145,7 +145,7 @@ cpu = CPU(None, None) cpu.setup_once() looptoken = JitCellToken() - cpu.compile_loop(None, inputargs, operations, looptoken) + cpu.compile_loop(inputargs, operations, looptoken) args = [-13 , 10 , 10 , 8 , -8 , -16 , -18 , 46 , -12 , 26] deadframe = cpu.execute_token(looptoken, *args) assert cpu.get_int_value(deadframe, 0) == 0 @@ -252,7 +252,7 @@ cpu = CPU(None, None) cpu.setup_once() looptoken = JitCellToken() - cpu.compile_loop(None, inputargs, operations, looptoken) + cpu.compile_loop(inputargs, operations, looptoken) args = [17 , -20 , -6 , 6 , 1 , 13 , 13 , 9 , 49 , 8] deadframe = cpu.execute_token(looptoken, *args) assert cpu.get_int_value(deadframe, 0) == 0 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 @@ -75,7 +75,7 @@ ResOperation(rop.FINISH, [inp[1]], None, descr=BasicFinalDescr(1)), ] operations[-2].setfailargs(out) - cpu.compile_loop(None, inp, operations, looptoken) + cpu.compile_loop(inp, operations, looptoken) args = [i for i in range(1, 15)] deadframe = self.cpu.execute_token(looptoken, *args) output = [self.cpu.get_int_value(deadframe, i - 1) for i in range(1, 15)] @@ -117,9 +117,9 @@ i1 = int_sub(i0, 1) finish(i1) ''') - self.cpu.compile_loop(None, loop2.inputargs, loop2.operations, lt2) - self.cpu.compile_loop(None, loop3.inputargs, loop3.operations, lt3) - self.cpu.compile_loop(None, loop1.inputargs, loop1.operations, lt1) + self.cpu.compile_loop(loop2.inputargs, loop2.operations, lt2) + self.cpu.compile_loop(loop3.inputargs, loop3.operations, lt3) + self.cpu.compile_loop(loop1.inputargs, loop1.operations, lt1) df = self.cpu.execute_token(lt1, 10) assert self.cpu.get_int_value(df, 0) == 7 @@ -214,7 +214,7 @@ ops = "".join(ops) loop = parse(ops) looptoken = JitCellToken() - self.cpu.compile_loop(None, loop.inputargs, loop.operations, looptoken) + self.cpu.compile_loop(loop.inputargs, loop.operations, looptoken) ARGS = [lltype.Signed] * numargs RES = lltype.Signed args = [i+1 for i in range(numargs)] @@ -246,7 +246,7 @@ try: self.cpu.assembler.set_debug(True) looptoken = JitCellToken() - self.cpu.compile_loop(None, ops.inputargs, ops.operations, looptoken) + self.cpu.compile_loop(ops.inputargs, ops.operations, looptoken) self.cpu.execute_token(looptoken, 0) # check debugging info struct = self.cpu.assembler.loop_run_counters[0] @@ -280,7 +280,7 @@ faildescr = BasicFailDescr(2) loop = parse(ops, self.cpu, namespace=locals()) looptoken = JitCellToken() From noreply at buildbot.pypy.org Sun Sep 22 23:55:07 2013 From: noreply at buildbot.pypy.org (rlamy) Date: Sun, 22 Sep 2013 23:55:07 +0200 (CEST) Subject: [pypy-commit] pypy less-stringly-ops: auto-register HLOperation classes Message-ID: <20130922215507.0A9BB1C0203@cobra.cs.uni-duesseldorf.de> Author: Ronan Lamy Branch: less-stringly-ops Changeset: r67064:6c95c231dd89 Date: 2013-09-22 22:54 +0100 http://bitbucket.org/pypy/pypy/changeset/6c95c231dd89/ Log: auto-register HLOperation classes diff --git a/rpython/flowspace/model.py b/rpython/flowspace/model.py --- a/rpython/flowspace/model.py +++ b/rpython/flowspace/model.py @@ -394,7 +394,6 @@ return Constant(obj) class SpaceOperation(object): - __slots__ = "opname args result offset".split() def __init__(self, opname, args, result, offset=-1): self.opname = intern(opname) # operation name diff --git a/rpython/flowspace/operation.py b/rpython/flowspace/operation.py --- a/rpython/flowspace/operation.py +++ b/rpython/flowspace/operation.py @@ -42,7 +42,14 @@ func2op = {} +class HLOperationMeta(type): + def __init__(cls, name, bases, attrdict): + type.__init__(cls, name, bases, attrdict) + if hasattr(cls, 'opname'): + setattr(op, cls.opname, cls) + class HLOperation(SpaceOperation): + __metaclass__ = HLOperationMeta pure = False def __init__(self, *args): @@ -103,9 +110,8 @@ def add_operator(name, arity, pyfunc=None, pure=False, ovf=False): operator_func = getattr(operator, name, None) base_cls = PureOperation if pure else HLOperation - cls = type(name, (base_cls,), {'opname': name, 'arity': arity, + cls = HLOperationMeta(name, (base_cls,), {'opname': name, 'arity': arity, 'can_overflow': ovf, 'canraise': []}) - setattr(op, name, cls) if pyfunc is not None: func2op[pyfunc] = cls if operator_func: @@ -306,7 +312,6 @@ self.args = [w_base, w_exponent, w_mod] self.result = Variable() self.offset = -1 -op.pow = Pow class Iter(HLOperation): @@ -322,7 +327,6 @@ iterable = w_iterable.value if isinstance(iterable, unrolling_iterable): return const(iterable.get_unroller()) -op.iter = Iter class Next(HLOperation): opname = 'next' @@ -347,7 +351,6 @@ w_item = frame.do_op(self) frame.guessexception([StopIteration, RuntimeError], force=True) return w_item -op.next = Next class GetAttr(HLOperation): opname = 'getattr' @@ -376,7 +379,6 @@ return const(result) except WrapException: pass -op.getattr = GetAttr class CallOp(HLOperation): @property @@ -395,12 +397,9 @@ class SimpleCall(CallOp): opname = 'simple_call' -op.simple_call = SimpleCall - class CallArgs(CallOp): opname = 'call_args' -op.call_args = CallArgs # Other functions that get directly translated to SpaceOperators func2op[type] = op.type From noreply at buildbot.pypy.org Mon Sep 23 08:53:45 2013 From: noreply at buildbot.pypy.org (mattip) Date: Mon, 23 Sep 2013 08:53:45 +0200 (CEST) Subject: [pypy-commit] pypy pypy-pyarray: update whatsnew Message-ID: <20130923065345.28B051C0203@cobra.cs.uni-duesseldorf.de> Author: Matti Picus Branch: pypy-pyarray Changeset: r67066:234a5f5ac186 Date: 2013-09-23 09:49 +0300 http://bitbucket.org/pypy/pypy/changeset/234a5f5ac186/ Log: update 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 @@ -52,6 +52,10 @@ .. branch: ndarray-subtype Allow subclassing ndarray, i.e. matrix +.. branch: pypy-pyarray +Implement much of numpy's c api in cpyext, allows (slow) access to ndarray +from c + .. branch: kill-ootype .. branch: fast-slowpath From noreply at buildbot.pypy.org Mon Sep 23 08:53:46 2013 From: noreply at buildbot.pypy.org (mattip) Date: Mon, 23 Sep 2013 08:53:46 +0200 (CEST) Subject: [pypy-commit] pypy pypy-pyarray: close branch Message-ID: <20130923065346.426E71C103B@cobra.cs.uni-duesseldorf.de> Author: Matti Picus Branch: pypy-pyarray Changeset: r67067:a7a96346a835 Date: 2013-09-23 09:49 +0300 http://bitbucket.org/pypy/pypy/changeset/a7a96346a835/ Log: close branch From noreply at buildbot.pypy.org Mon Sep 23 08:53:48 2013 From: noreply at buildbot.pypy.org (mattip) Date: Mon, 23 Sep 2013 08:53:48 +0200 (CEST) Subject: [pypy-commit] pypy default: merge pypy-pyarray which implements much of numpy's c api to access ndarray from c and also array.nozero Message-ID: <20130923065348.594731C0203@cobra.cs.uni-duesseldorf.de> Author: Matti Picus Branch: Changeset: r67068:a029cfc6c67b Date: 2013-09-23 09:52 +0300 http://bitbucket.org/pypy/pypy/changeset/a029cfc6c67b/ Log: merge pypy-pyarray which implements much of numpy's c api to access ndarray from c and also array.nozero diff too long, truncating to 2000 out of 2416 lines diff --git a/lib_pypy/numpy.py b/lib_pypy/numpy.py --- a/lib_pypy/numpy.py +++ b/lib_pypy/numpy.py @@ -1,5 +1,12 @@ -raise ImportError( - "The 'numpy' module of PyPy is in-development and not complete. " - "To try it out anyway, you can either import from 'numpypy', " - "or just write 'import numpypy' first in your program and then " - "import from 'numpy' as usual.") +import warnings +import sys +if 'numpypy' not in sys.modules: + warnings.warn( + "The 'numpy' module of PyPy is in-development and not complete. " + "To avoid this warning, write 'import numpypy as numpy'. ", + UserWarning) # XXX is this the best warning type? + +from numpypy import * +import numpypy +__all__ = numpypy.__all__ +del numpypy diff --git a/lib_pypy/numpypy/__init__.py b/lib_pypy/numpypy/__init__.py --- a/lib_pypy/numpypy/__init__.py +++ b/lib_pypy/numpypy/__init__.py @@ -6,9 +6,19 @@ from __builtin__ import bool, int, long, float, complex, object, unicode, str from core import abs, max, min -__all__ = [] +__version__ = '1.7.0' + +import os +def get_include(): + head, tail = os.path.split(os.path.dirname(os.path.abspath(__file__))) + return os.path.join(head, '../include') + + +__all__ = ['__version__', 'get_include'] __all__ += core.__all__ __all__ += lib.__all__ -import sys -sys.modules.setdefault('numpy', sys.modules['numpypy']) +#import sys +#sys.modules.setdefault('numpy', sys.modules['numpypy']) + + diff --git a/lib_pypy/numpypy/core/fromnumeric.py b/lib_pypy/numpypy/core/fromnumeric.py --- a/lib_pypy/numpypy/core/fromnumeric.py +++ b/lib_pypy/numpypy/core/fromnumeric.py @@ -1133,7 +1133,13 @@ (array([1, 1, 1, 2, 2, 2]), array([0, 1, 2, 0, 1, 2])) """ - raise NotImplementedError('Waiting on interp level method') + try: + nonzero = a.nonzero + except AttributeError: + res = _wrapit(a, 'nonzero') + else: + res = nonzero() + return res def shape(a): diff --git a/pypy/doc/whatsnew-head.rst b/pypy/doc/whatsnew-head.rst --- a/pypy/doc/whatsnew-head.rst +++ b/pypy/doc/whatsnew-head.rst @@ -52,6 +52,10 @@ .. branch: ndarray-subtype Allow subclassing ndarray, i.e. matrix +.. branch: pypy-pyarray +Implement much of numpy's c api in cpyext, allows (slow) access to ndarray +from c + .. branch: kill-ootype .. branch: fast-slowpath 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 @@ -36,6 +36,7 @@ import pypy.module.cpyext.object import pypy.module.cpyext.stringobject import pypy.module.cpyext.tupleobject +import pypy.module.cpyext.ndarrayobject import pypy.module.cpyext.setobject import pypy.module.cpyext.dictobject import pypy.module.cpyext.intobject diff --git a/pypy/module/cpyext/api.py b/pypy/module/cpyext/api.py --- a/pypy/module/cpyext/api.py +++ b/pypy/module/cpyext/api.py @@ -130,11 +130,7 @@ udir.join('pypy_macros.h').write("/* Will be filled later */\n") globals().update(rffi_platform.configure(CConfig_constants)) -def copy_header_files(dstdir): - assert dstdir.check(dir=True) - headers = include_dir.listdir('*.h') + include_dir.listdir('*.inl') - for name in ("pypy_decl.h", "pypy_macros.h"): - headers.append(udir.join(name)) +def _copy_header_files(headers, dstdir): for header in headers: target = dstdir.join(header.basename) try: @@ -145,6 +141,25 @@ target.chmod(0444) # make the file read-only, to make sure that nobody # edits it by mistake +def copy_header_files(dstdir): + # XXX: 20 lines of code to recursively copy a directory, really?? + assert dstdir.check(dir=True) + headers = include_dir.listdir('*.h') + include_dir.listdir('*.inl') + for name in ("pypy_decl.h", "pypy_macros.h"): + headers.append(udir.join(name)) + _copy_header_files(headers, dstdir) + + try: + dstdir.mkdir('numpy') + except py.error.EEXIST: + pass + numpy_dstdir = dstdir / 'numpy' + + numpy_include_dir = include_dir / 'numpy' + numpy_headers = numpy_include_dir.listdir('*.h') + numpy_include_dir.listdir('*.inl') + _copy_header_files(numpy_headers, numpy_dstdir) + + class NotSpecified(object): pass _NOT_SPECIFIED = NotSpecified() @@ -288,9 +303,23 @@ elif isinstance(input_arg, W_Root): arg = input_arg else: - arg = from_ref(space, + try: + arg = from_ref(space, rffi.cast(PyObject, input_arg)) + except TypeError, e: + err = OperationError(space.w_TypeError, + space.wrap( + "could not cast arg to PyObject")) + if not catch_exception: + raise err + state = space.fromcache(State) + state.set_exception(err) + if is_PyObject(restype): + return None + else: + return api_function.error_value else: + # convert to a wrapped object arg = input_arg newargs += (arg, ) try: @@ -309,7 +338,7 @@ return api_function.error_value if not we_are_translated(): got_integer = isinstance(res, (int, long, float)) - assert got_integer == expect_integer + assert got_integer == expect_integer,'got %r not integer' % res if res is None: return None elif isinstance(res, Reference): @@ -386,6 +415,16 @@ 'PyThread_ReInitTLS', 'PyStructSequence_InitType', 'PyStructSequence_New', + + 'PyFunction_Type', 'PyMethod_Type', 'PyRange_Type', 'PyTraceBack_Type', + + 'PyArray_Type', '_PyArray_FILLWBYTE', '_PyArray_ZEROS', '_PyArray_CopyInto', + + 'Py_DebugFlag', 'Py_VerboseFlag', 'Py_InteractiveFlag', 'Py_InspectFlag', + 'Py_OptimizeFlag', 'Py_NoSiteFlag', 'Py_BytesWarningFlag', 'Py_UseClassExceptionsFlag', + 'Py_FrozenFlag', 'Py_TabcheckFlag', 'Py_UnicodeFlag', 'Py_IgnoreEnvironmentFlag', + 'Py_DivisionWarningFlag', 'Py_DontWriteBytecodeFlag', 'Py_NoUserSiteDirectory', + '_Py_QnewFlag', 'Py_Py3kWarningFlag', 'Py_HashRandomizationFlag', '_Py_PackageContext', ] TYPES = {} GLOBALS = { # this needs to include all prebuilt pto, otherwise segfaults occur @@ -975,6 +1014,8 @@ source_dir / "capsule.c", source_dir / "pysignals.c", source_dir / "pythread.c", + source_dir / "ndarrayobject.c", + source_dir / "missing.c", ], separate_module_sources=separate_module_sources, export_symbols=export_symbols_eci, diff --git a/pypy/module/cpyext/include/Python.h b/pypy/module/cpyext/include/Python.h --- a/pypy/module/cpyext/include/Python.h +++ b/pypy/module/cpyext/include/Python.h @@ -126,6 +126,9 @@ #include "pysignals.h" #include "pythread.h" +/* Missing definitions */ +#include "missing.h" + // XXX This shouldn't be included here #include "structmember.h" diff --git a/pypy/module/cpyext/include/boolobject.h b/pypy/module/cpyext/include/boolobject.h --- a/pypy/module/cpyext/include/boolobject.h +++ b/pypy/module/cpyext/include/boolobject.h @@ -7,6 +7,8 @@ extern "C" { #endif +#define PyBoolObject PyIntObject + #define Py_False ((PyObject *) &_Py_ZeroStruct) #define Py_True ((PyObject *) &_Py_TrueStruct) diff --git a/pypy/module/cpyext/include/complexobject.h b/pypy/module/cpyext/include/complexobject.h --- a/pypy/module/cpyext/include/complexobject.h +++ b/pypy/module/cpyext/include/complexobject.h @@ -6,6 +6,9 @@ extern "C" { #endif +/* fake PyComplexObject so that code that doesn't do direct field access works */ +#define PyComplexObject PyObject + typedef struct Py_complex_t { double real; double imag; @@ -13,6 +16,7 @@ /* generated function */ PyAPI_FUNC(void) _PyComplex_AsCComplex(PyObject *, Py_complex *); +PyAPI_FUNC(PyObject *) _PyComplex_FromCComplex(Py_complex *); Py_LOCAL_INLINE(Py_complex) PyComplex_AsCComplex(PyObject *obj) { @@ -21,7 +25,12 @@ return result; } -#define PyComplex_FromCComplex(c) _PyComplex_FromCComplex(&c) +// shmuller 2013/07/30: Make a function, since macro will fail in C++ due to +// const correctness if called with "const Py_complex" +//#define PyComplex_FromCComplex(c) _PyComplex_FromCComplex(&c) +Py_LOCAL_INLINE(PyObject *) PyComplex_FromCComplex(Py_complex c) { + return _PyComplex_FromCComplex(&c); +} #ifdef __cplusplus } diff --git a/pypy/module/cpyext/include/funcobject.h b/pypy/module/cpyext/include/funcobject.h --- a/pypy/module/cpyext/include/funcobject.h +++ b/pypy/module/cpyext/include/funcobject.h @@ -12,6 +12,8 @@ PyObject *func_name; /* The __name__ attribute, a string object */ } PyFunctionObject; +PyAPI_DATA(PyTypeObject) PyFunction_Type; + #define PyFunction_GET_CODE(obj) PyFunction_GetCode((PyObject*)(obj)) #define PyMethod_GET_FUNCTION(obj) PyMethod_Function((PyObject*)(obj)) diff --git a/pypy/module/cpyext/include/missing.h b/pypy/module/cpyext/include/missing.h new file mode 100644 --- /dev/null +++ b/pypy/module/cpyext/include/missing.h @@ -0,0 +1,17 @@ + +/* Definitions from missing header files */ + +#ifndef Py_MISSING_H +#define Py_MISSING_H +#ifdef __cplusplus +extern "C" { +#endif + +PyAPI_DATA(PyTypeObject) PyMethod_Type; +PyAPI_DATA(PyTypeObject) PyRange_Type; +PyAPI_DATA(PyTypeObject) PyTraceBack_Type; + +#ifdef __cplusplus +} +#endif +#endif /* !Py_MISSING_H */ diff --git a/pypy/module/cpyext/include/modsupport.h b/pypy/module/cpyext/include/modsupport.h --- a/pypy/module/cpyext/include/modsupport.h +++ b/pypy/module/cpyext/include/modsupport.h @@ -56,6 +56,7 @@ #define PyMODINIT_FUNC void #endif +PyAPI_DATA(char *) _Py_PackageContext; #ifdef __cplusplus } diff --git a/pypy/module/cpyext/include/numpy/arrayobject.h b/pypy/module/cpyext/include/numpy/arrayobject.h new file mode 100644 --- /dev/null +++ b/pypy/module/cpyext/include/numpy/arrayobject.h @@ -0,0 +1,239 @@ + +/* NDArray object interface - S. H. Muller, 2013/07/26 */ + +#ifndef Py_NDARRAYOBJECT_H +#define Py_NDARRAYOBJECT_H +#ifdef __cplusplus +extern "C" { +#endif + +#include "old_defines.h" + +#define NPY_INLINE +#define NPY_UNUSED(x) x +#define PyArray_MAX(a,b) (((a)>(b))?(a):(b)) +#define PyArray_MIN(a,b) (((a)<(b))?(a):(b)) + +/* fake PyArrayObject so that code that doesn't do direct field access works */ +#define PyArrayObject PyObject +#define PyArray_Descr PyObject + +extern PyTypeObject PyArray_Type; + +typedef unsigned char npy_bool; +typedef unsigned char npy_uint8; +typedef int npy_int; + +#ifndef npy_intp +#define npy_intp long +#endif +#ifndef NPY_INTP_FMT +#define NPY_INTP_FMT "ld" +#endif +#ifndef import_array +#define import_array() +#endif + +#define NPY_MAXDIMS 32 + +typedef struct { + npy_intp *ptr; + int len; +} PyArray_Dims; + +/* data types copied from numpy/ndarraytypes.h + * keep numbers in sync with micronumpy.interp_dtype.DTypeCache + */ +enum NPY_TYPES { NPY_BOOL=0, + NPY_BYTE, NPY_UBYTE, + NPY_SHORT, NPY_USHORT, + NPY_INT, NPY_UINT, + NPY_LONG, NPY_ULONG, + NPY_LONGLONG, NPY_ULONGLONG, + NPY_FLOAT, NPY_DOUBLE, NPY_LONGDOUBLE, + NPY_CFLOAT, NPY_CDOUBLE, NPY_CLONGDOUBLE, + NPY_OBJECT=17, + NPY_STRING, NPY_UNICODE, + NPY_VOID, + /* + * New 1.6 types appended, may be integrated + * into the above in 2.0. + */ + NPY_DATETIME, NPY_TIMEDELTA, NPY_HALF, + + NPY_NTYPES, + NPY_NOTYPE, + NPY_CHAR, /* special flag */ + NPY_USERDEF=256, /* leave room for characters */ + + /* The number of types not including the new 1.6 types */ + NPY_NTYPES_ABI_COMPATIBLE=21 +}; + +#define NPY_INT8 NPY_BYTE +#define NPY_UINT8 NPY_UBYTE +#define NPY_INT16 NPY_SHORT +#define NPY_UINT16 NPY_USHORT +#define NPY_INT32 NPY_INT +#define NPY_UINT32 NPY_UINT +#define NPY_INT64 NPY_LONG +#define NPY_UINT64 NPY_ULONG +#define NPY_FLOAT32 NPY_FLOAT +#define NPY_FLOAT64 NPY_DOUBLE +#define NPY_COMPLEX32 NPY_CFLOAT +#define NPY_COMPLEX64 NPY_CDOUBLE + +#define PyTypeNum_ISBOOL(type) ((type) == NPY_BOOL) +#define PyTypeNum_ISINTEGER(type) (((type) >= NPY_BYTE) && \ + ((type) <= NPY_ULONGLONG)) +#define PyTypeNum_ISFLOAT(type) ((((type) >= NPY_FLOAT) && \ + ((type) <= NPY_LONGDOUBLE)) || \ + ((type) == NPY_HALF)) +#define PyTypeNum_ISCOMPLEX(type) (((type) >= NPY_CFLOAT) && \ + ((type) <= NPY_CLONGDOUBLE)) + +#define PyArray_ISBOOL(arr) (PyTypeNum_ISBOOL(PyArray_TYPE(arr))) +#define PyArray_ISINTEGER(arr) (PyTypeNum_ISINTEGER(PyArray_TYPE(arr))) +#define PyArray_ISFLOAT(arr) (PyTypeNum_ISFLOAT(PyArray_TYPE(arr))) +#define PyArray_ISCOMPLEX(arr) (PyTypeNum_ISCOMPLEX(PyArray_TYPE(arr))) + + +/* flags */ +#define NPY_ARRAY_C_CONTIGUOUS 0x0001 +#define NPY_ARRAY_F_CONTIGUOUS 0x0002 +#define NPY_ARRAY_OWNDATA 0x0004 +#define NPY_ARRAY_FORCECAST 0x0010 +#define NPY_ARRAY_ENSURECOPY 0x0020 +#define NPY_ARRAY_ENSUREARRAY 0x0040 +#define NPY_ARRAY_ELEMENTSTRIDES 0x0080 +#define NPY_ARRAY_ALIGNED 0x0100 +#define NPY_ARRAY_NOTSWAPPED 0x0200 +#define NPY_ARRAY_WRITEABLE 0x0400 +#define NPY_ARRAY_UPDATEIFCOPY 0x1000 + +#define NPY_ARRAY_BEHAVED (NPY_ARRAY_ALIGNED | \ + NPY_ARRAY_WRITEABLE) +#define NPY_ARRAY_BEHAVED_NS (NPY_ARRAY_ALIGNED | \ + NPY_ARRAY_WRITEABLE | \ + NPY_ARRAY_NOTSWAPPED) +#define NPY_ARRAY_CARRAY (NPY_ARRAY_C_CONTIGUOUS | \ + NPY_ARRAY_BEHAVED) +#define NPY_ARRAY_CARRAY_RO (NPY_ARRAY_C_CONTIGUOUS | \ + NPY_ARRAY_ALIGNED) +#define NPY_ARRAY_FARRAY (NPY_ARRAY_F_CONTIGUOUS | \ + NPY_ARRAY_BEHAVED) +#define NPY_ARRAY_FARRAY_RO (NPY_ARRAY_F_CONTIGUOUS | \ + NPY_ARRAY_ALIGNED) +#define NPY_ARRAY_DEFAULT (NPY_ARRAY_CARRAY) +#define NPY_ARRAY_IN_ARRAY (NPY_ARRAY_CARRAY_RO) +#define NPY_ARRAY_OUT_ARRAY (NPY_ARRAY_CARRAY) +#define NPY_ARRAY_INOUT_ARRAY (NPY_ARRAY_CARRAY | \ + NPY_ARRAY_UPDATEIFCOPY) +#define NPY_ARRAY_IN_FARRAY (NPY_ARRAY_FARRAY_RO) +#define NPY_ARRAY_OUT_FARRAY (NPY_ARRAY_FARRAY) +#define NPY_ARRAY_INOUT_FARRAY (NPY_ARRAY_FARRAY | \ + NPY_ARRAY_UPDATEIFCOPY) + +#define NPY_ARRAY_UPDATE_ALL (NPY_ARRAY_C_CONTIGUOUS | \ + NPY_ARRAY_F_CONTIGUOUS | \ + NPY_ARRAY_ALIGNED) + +#define NPY_FARRAY NPY_ARRAY_FARRAY +#define NPY_CARRAY NPY_ARRAY_CARRAY + +#define PyArray_CHKFLAGS(m, flags) (PyArray_FLAGS(m) & (flags)) + +#define PyArray_ISCONTIGUOUS(m) PyArray_CHKFLAGS(m, NPY_ARRAY_C_CONTIGUOUS) +#define PyArray_ISWRITEABLE(m) PyArray_CHKFLAGS(m, NPY_ARRAY_WRITEABLE) +#define PyArray_ISALIGNED(m) PyArray_CHKFLAGS(m, NPY_ARRAY_ALIGNED) + +#define PyArray_IS_C_CONTIGUOUS(m) PyArray_CHKFLAGS(m, NPY_ARRAY_C_CONTIGUOUS) +#define PyArray_IS_F_CONTIGUOUS(m) PyArray_CHKFLAGS(m, NPY_ARRAY_F_CONTIGUOUS) + +#define PyArray_FLAGSWAP(m, flags) (PyArray_CHKFLAGS(m, flags) && \ + PyArray_ISNOTSWAPPED(m)) + +#define PyArray_ISCARRAY(m) PyArray_FLAGSWAP(m, NPY_ARRAY_CARRAY) +#define PyArray_ISCARRAY_RO(m) PyArray_FLAGSWAP(m, NPY_ARRAY_CARRAY_RO) +#define PyArray_ISFARRAY(m) PyArray_FLAGSWAP(m, NPY_ARRAY_FARRAY) +#define PyArray_ISFARRAY_RO(m) PyArray_FLAGSWAP(m, NPY_ARRAY_FARRAY_RO) +#define PyArray_ISBEHAVED(m) PyArray_FLAGSWAP(m, NPY_ARRAY_BEHAVED) +#define PyArray_ISBEHAVED_RO(m) PyArray_FLAGSWAP(m, NPY_ARRAY_ALIGNED) + +#define PyArray_ISONESEGMENT(arr) (1) +#define PyArray_ISNOTSWAPPED(arr) (1) +#define PyArray_ISBYTESWAPPED(arr) (0) + + +/* functions */ +#ifndef PyArray_NDIM + +#define PyArray_Check _PyArray_Check +#define PyArray_CheckExact _PyArray_CheckExact +#define PyArray_FLAGS _PyArray_FLAGS + +#define PyArray_NDIM _PyArray_NDIM +#define PyArray_DIM _PyArray_DIM +#define PyArray_STRIDE _PyArray_STRIDE +#define PyArray_SIZE _PyArray_SIZE +#define PyArray_ITEMSIZE _PyArray_ITEMSIZE +#define PyArray_NBYTES _PyArray_NBYTES +#define PyArray_TYPE _PyArray_TYPE +#define PyArray_DATA _PyArray_DATA + +#define PyArray_Size PyArray_SIZE +#define PyArray_BYTES(arr) ((char *)PyArray_DATA(arr)) + +#define PyArray_FromAny _PyArray_FromAny +#define PyArray_FromObject _PyArray_FromObject +#define PyArray_ContiguousFromObject PyArray_FromObject +#define PyArray_ContiguousFromAny PyArray_FromObject + +#define PyArray_FROMANY(obj, typenum, min, max, requirements) (obj) +#define PyArray_FROM_OTF(obj, typenum, requirements) \ + PyArray_FromObject(obj, typenum, 0, 0) + +#define PyArray_New _PyArray_New +#define PyArray_SimpleNew _PyArray_SimpleNew +#define PyArray_SimpleNewFromData _PyArray_SimpleNewFromData +#define PyArray_SimpleNewFromDataOwning _PyArray_SimpleNewFromDataOwning + +#define PyArray_EMPTY(nd, dims, type_num, fortran) \ + PyArray_SimpleNew(nd, dims, type_num) + +void _PyArray_FILLWBYTE(PyObject* obj, int val); +PyObject* _PyArray_ZEROS(int nd, npy_intp* dims, int type_num, int fortran); +int _PyArray_CopyInto(PyArrayObject* dest, PyArrayObject* src); + +#define PyArray_FILLWBYTE _PyArray_FILLWBYTE +#define PyArray_ZEROS _PyArray_ZEROS +#define PyArray_CopyInto _PyArray_CopyInto + +#define PyArray_Resize(self, newshape, refcheck, fortran) (NULL) + +/* Don't use these in loops! */ + +#define PyArray_GETPTR1(obj, i) ((void *)(PyArray_BYTES(obj) + \ + (i)*PyArray_STRIDE(obj,0))) + +#define PyArray_GETPTR2(obj, i, j) ((void *)(PyArray_BYTES(obj) + \ + (i)*PyArray_STRIDE(obj,0) + \ + (j)*PyArray_STRIDE(obj,1))) + +#define PyArray_GETPTR3(obj, i, j, k) ((void *)(PyArray_BYTES(obj) + \ + (i)*PyArray_STRIDE(obj,0) + \ + (j)*PyArray_STRIDE(obj,1) + \ + (k)*PyArray_STRIDE(obj,2))) + +#define PyArray_GETPTR4(obj, i, j, k, l) ((void *)(PyArray_BYTES(obj) + \ + (i)*PyArray_STRIDE(obj,0) + \ + (j)*PyArray_STRIDE(obj,1) + \ + (k)*PyArray_STRIDE(obj,2) + \ + (l)*PyArray_STRIDE(obj,3))) + +#endif + +#ifdef __cplusplus +} +#endif +#endif /* !Py_NDARRAYOBJECT_H */ diff --git a/pypy/module/cpyext/include/numpy/npy_3kcompat.h b/pypy/module/cpyext/include/numpy/npy_3kcompat.h new file mode 100644 diff --git a/pypy/module/cpyext/include/numpy/old_defines.h b/pypy/module/cpyext/include/numpy/old_defines.h new file mode 100644 --- /dev/null +++ b/pypy/module/cpyext/include/numpy/old_defines.h @@ -0,0 +1,189 @@ +/* This header is deprecated as of NumPy 1.7 */ +#ifndef OLD_DEFINES_H +#define OLD_DEFINES_H + +/* +#if defined(NPY_NO_DEPRECATED_API) && NPY_NO_DEPRECATED_API >= NPY_1_7_API_VERSION +#error The header "old_defines.h" is deprecated as of NumPy 1.7. +#endif +*/ + +#define NDARRAY_VERSION NPY_VERSION + +#define PyArray_MIN_BUFSIZE NPY_MIN_BUFSIZE +#define PyArray_MAX_BUFSIZE NPY_MAX_BUFSIZE +#define PyArray_BUFSIZE NPY_BUFSIZE + +#define PyArray_PRIORITY NPY_PRIORITY +#define PyArray_SUBTYPE_PRIORITY NPY_PRIORITY +#define PyArray_NUM_FLOATTYPE NPY_NUM_FLOATTYPE + +#define NPY_MAX PyArray_MAX +#define NPY_MIN PyArray_MIN + +#define PyArray_TYPES NPY_TYPES +#define PyArray_BOOL NPY_BOOL +#define PyArray_BYTE NPY_BYTE +#define PyArray_UBYTE NPY_UBYTE +#define PyArray_SHORT NPY_SHORT +#define PyArray_USHORT NPY_USHORT +#define PyArray_INT NPY_INT +#define PyArray_UINT NPY_UINT +#define PyArray_LONG NPY_LONG +#define PyArray_ULONG NPY_ULONG +#define PyArray_LONGLONG NPY_LONGLONG +#define PyArray_ULONGLONG NPY_ULONGLONG +#define PyArray_HALF NPY_HALF +#define PyArray_FLOAT NPY_FLOAT +#define PyArray_DOUBLE NPY_DOUBLE +#define PyArray_LONGDOUBLE NPY_LONGDOUBLE +#define PyArray_CFLOAT NPY_CFLOAT +#define PyArray_CDOUBLE NPY_CDOUBLE +#define PyArray_CLONGDOUBLE NPY_CLONGDOUBLE +#define PyArray_OBJECT NPY_OBJECT +#define PyArray_STRING NPY_STRING +#define PyArray_UNICODE NPY_UNICODE +#define PyArray_VOID NPY_VOID +#define PyArray_DATETIME NPY_DATETIME +#define PyArray_TIMEDELTA NPY_TIMEDELTA +#define PyArray_NTYPES NPY_NTYPES +#define PyArray_NOTYPE NPY_NOTYPE +#define PyArray_CHAR NPY_CHAR +#define PyArray_USERDEF NPY_USERDEF +#define PyArray_NUMUSERTYPES NPY_NUMUSERTYPES + +#define PyArray_INTP NPY_INTP +#define PyArray_UINTP NPY_UINTP + +#define PyArray_INT8 NPY_INT8 +#define PyArray_UINT8 NPY_UINT8 +#define PyArray_INT16 NPY_INT16 +#define PyArray_UINT16 NPY_UINT16 +#define PyArray_INT32 NPY_INT32 +#define PyArray_UINT32 NPY_UINT32 + +#ifdef NPY_INT64 +#define PyArray_INT64 NPY_INT64 +#define PyArray_UINT64 NPY_UINT64 +#endif + +#ifdef NPY_INT128 +#define PyArray_INT128 NPY_INT128 +#define PyArray_UINT128 NPY_UINT128 +#endif + +#ifdef NPY_FLOAT16 +#define PyArray_FLOAT16 NPY_FLOAT16 +#define PyArray_COMPLEX32 NPY_COMPLEX32 +#endif + +#ifdef NPY_FLOAT80 +#define PyArray_FLOAT80 NPY_FLOAT80 +#define PyArray_COMPLEX160 NPY_COMPLEX160 +#endif + +#ifdef NPY_FLOAT96 +#define PyArray_FLOAT96 NPY_FLOAT96 +#define PyArray_COMPLEX192 NPY_COMPLEX192 +#endif + +#ifdef NPY_FLOAT128 +#define PyArray_FLOAT128 NPY_FLOAT128 +#define PyArray_COMPLEX256 NPY_COMPLEX256 +#endif + +#define PyArray_FLOAT32 NPY_FLOAT32 +#define PyArray_COMPLEX64 NPY_COMPLEX64 +#define PyArray_FLOAT64 NPY_FLOAT64 +#define PyArray_COMPLEX128 NPY_COMPLEX128 + + +#define PyArray_TYPECHAR NPY_TYPECHAR +#define PyArray_BOOLLTR NPY_BOOLLTR +#define PyArray_BYTELTR NPY_BYTELTR +#define PyArray_UBYTELTR NPY_UBYTELTR +#define PyArray_SHORTLTR NPY_SHORTLTR +#define PyArray_USHORTLTR NPY_USHORTLTR +#define PyArray_INTLTR NPY_INTLTR +#define PyArray_UINTLTR NPY_UINTLTR +#define PyArray_LONGLTR NPY_LONGLTR +#define PyArray_ULONGLTR NPY_ULONGLTR +#define PyArray_LONGLONGLTR NPY_LONGLONGLTR +#define PyArray_ULONGLONGLTR NPY_ULONGLONGLTR +#define PyArray_HALFLTR NPY_HALFLTR +#define PyArray_FLOATLTR NPY_FLOATLTR +#define PyArray_DOUBLELTR NPY_DOUBLELTR +#define PyArray_LONGDOUBLELTR NPY_LONGDOUBLELTR +#define PyArray_CFLOATLTR NPY_CFLOATLTR +#define PyArray_CDOUBLELTR NPY_CDOUBLELTR +#define PyArray_CLONGDOUBLELTR NPY_CLONGDOUBLELTR +#define PyArray_OBJECTLTR NPY_OBJECTLTR +#define PyArray_STRINGLTR NPY_STRINGLTR +#define PyArray_STRINGLTR2 NPY_STRINGLTR2 +#define PyArray_UNICODELTR NPY_UNICODELTR +#define PyArray_VOIDLTR NPY_VOIDLTR +#define PyArray_DATETIMELTR NPY_DATETIMELTR +#define PyArray_TIMEDELTALTR NPY_TIMEDELTALTR +#define PyArray_CHARLTR NPY_CHARLTR +#define PyArray_INTPLTR NPY_INTPLTR +#define PyArray_UINTPLTR NPY_UINTPLTR +#define PyArray_GENBOOLLTR NPY_GENBOOLLTR +#define PyArray_SIGNEDLTR NPY_SIGNEDLTR +#define PyArray_UNSIGNEDLTR NPY_UNSIGNEDLTR +#define PyArray_FLOATINGLTR NPY_FLOATINGLTR +#define PyArray_COMPLEXLTR NPY_COMPLEXLTR + +#define PyArray_QUICKSORT NPY_QUICKSORT +#define PyArray_HEAPSORT NPY_HEAPSORT +#define PyArray_MERGESORT NPY_MERGESORT +#define PyArray_SORTKIND NPY_SORTKIND +#define PyArray_NSORTS NPY_NSORTS + +#define PyArray_NOSCALAR NPY_NOSCALAR +#define PyArray_BOOL_SCALAR NPY_BOOL_SCALAR +#define PyArray_INTPOS_SCALAR NPY_INTPOS_SCALAR +#define PyArray_INTNEG_SCALAR NPY_INTNEG_SCALAR +#define PyArray_FLOAT_SCALAR NPY_FLOAT_SCALAR +#define PyArray_COMPLEX_SCALAR NPY_COMPLEX_SCALAR +#define PyArray_OBJECT_SCALAR NPY_OBJECT_SCALAR +#define PyArray_SCALARKIND NPY_SCALARKIND +#define PyArray_NSCALARKINDS NPY_NSCALARKINDS + +#define PyArray_ANYORDER NPY_ANYORDER +#define PyArray_CORDER NPY_CORDER +#define PyArray_FORTRANORDER NPY_FORTRANORDER +#define PyArray_ORDER NPY_ORDER + +#define PyDescr_ISBOOL PyDataType_ISBOOL +#define PyDescr_ISUNSIGNED PyDataType_ISUNSIGNED +#define PyDescr_ISSIGNED PyDataType_ISSIGNED +#define PyDescr_ISINTEGER PyDataType_ISINTEGER +#define PyDescr_ISFLOAT PyDataType_ISFLOAT +#define PyDescr_ISNUMBER PyDataType_ISNUMBER +#define PyDescr_ISSTRING PyDataType_ISSTRING +#define PyDescr_ISCOMPLEX PyDataType_ISCOMPLEX +#define PyDescr_ISPYTHON PyDataType_ISPYTHON +#define PyDescr_ISFLEXIBLE PyDataType_ISFLEXIBLE +#define PyDescr_ISUSERDEF PyDataType_ISUSERDEF +#define PyDescr_ISEXTENDED PyDataType_ISEXTENDED +#define PyDescr_ISOBJECT PyDataType_ISOBJECT +#define PyDescr_HASFIELDS PyDataType_HASFIELDS + +#define PyArray_LITTLE NPY_LITTLE +#define PyArray_BIG NPY_BIG +#define PyArray_NATIVE NPY_NATIVE +#define PyArray_SWAP NPY_SWAP +#define PyArray_IGNORE NPY_IGNORE + +#define PyArray_NATBYTE NPY_NATBYTE +#define PyArray_OPPBYTE NPY_OPPBYTE + +#define PyArray_MAX_ELSIZE NPY_MAX_ELSIZE + +#define PyArray_USE_PYMEM NPY_USE_PYMEM + +#define PyArray_RemoveLargest PyArray_RemoveSmallest + +#define PyArray_UCS4 npy_ucs4 + +#endif diff --git a/pypy/module/cpyext/include/pythonrun.h b/pypy/module/cpyext/include/pythonrun.h --- a/pypy/module/cpyext/include/pythonrun.h +++ b/pypy/module/cpyext/include/pythonrun.h @@ -6,14 +6,32 @@ extern "C" { #endif - void Py_FatalError(const char *msg); +void Py_FatalError(const char *msg); -/* the -3 option will probably not be implemented */ -#define Py_Py3kWarningFlag 0 +/* taken from Python-2.7.3/Include/pydebug.h */ +PyAPI_DATA(int) Py_DebugFlag; +PyAPI_DATA(int) Py_VerboseFlag; +PyAPI_DATA(int) Py_InteractiveFlag; +PyAPI_DATA(int) Py_InspectFlag; +PyAPI_DATA(int) Py_OptimizeFlag; +PyAPI_DATA(int) Py_NoSiteFlag; +PyAPI_DATA(int) Py_BytesWarningFlag; +PyAPI_DATA(int) Py_UseClassExceptionsFlag; +PyAPI_DATA(int) Py_FrozenFlag; +PyAPI_DATA(int) Py_TabcheckFlag; +PyAPI_DATA(int) Py_UnicodeFlag; +PyAPI_DATA(int) Py_IgnoreEnvironmentFlag; +PyAPI_DATA(int) Py_DivisionWarningFlag; +PyAPI_DATA(int) Py_DontWriteBytecodeFlag; +PyAPI_DATA(int) Py_NoUserSiteDirectory; +/* _XXX Py_QnewFlag should go away in 3.0. It's true iff -Qnew is passed, + * on the command line, and is used in 2.2 by ceval.c to make all "/" divisions + * true divisions (which they will be in 3.0). */ +PyAPI_DATA(int) _Py_QnewFlag; +/* Warn about 3.x issues */ +PyAPI_DATA(int) Py_Py3kWarningFlag; +PyAPI_DATA(int) Py_HashRandomizationFlag; -#define Py_FrozenFlag 0 -#define Py_VerboseFlag 0 -#define Py_DebugFlag 1 typedef struct { int cf_flags; /* bitmask of CO_xxx flags relevant to future */ diff --git a/pypy/module/cpyext/ndarrayobject.py b/pypy/module/cpyext/ndarrayobject.py new file mode 100644 --- /dev/null +++ b/pypy/module/cpyext/ndarrayobject.py @@ -0,0 +1,246 @@ +""" + +Numpy C-API for PyPy - S. H. Muller, 2013/07/26 +""" + +from pypy.interpreter.error import OperationError +from rpython.rtyper.lltypesystem import rffi, lltype +from pypy.module.cpyext.api import cpython_api, Py_ssize_t, CANNOT_FAIL +from pypy.module.cpyext.api import PyObject +from pypy.module.micronumpy.interp_numarray import W_NDimArray, array +from pypy.module.micronumpy.interp_dtype import get_dtype_cache, W_Dtype +from pypy.module.micronumpy.arrayimpl.concrete import ConcreteArray +from pypy.module.micronumpy.arrayimpl.scalar import Scalar +from rpython.rlib.rawstorage import RAW_STORAGE_PTR + +NPY_C_CONTIGUOUS = 0x0001 +NPY_F_CONTIGUOUS = 0x0002 +NPY_OWNDATA = 0x0004 +NPY_FORCECAST = 0x0010 +NPY_ENSURECOPY = 0x0020 +NPY_ENSUREARRAY = 0x0040 +NPY_ELEMENTSTRIDES = 0x0080 +NPY_ALIGNED = 0x0100 +NPY_NOTSWAPPED = 0x0200 +NPY_WRITEABLE = 0x0400 +NPY_UPDATEIFCOPY = 0x1000 + +NPY_BEHAVED = NPY_ALIGNED | NPY_WRITEABLE +NPY_BEHAVED_NS = NPY_ALIGNED | NPY_WRITEABLE | NPY_NOTSWAPPED +NPY_CARRAY = NPY_C_CONTIGUOUS | NPY_BEHAVED +NPY_CARRAY_RO = NPY_C_CONTIGUOUS | NPY_ALIGNED +NPY_FARRAY = NPY_F_CONTIGUOUS | NPY_BEHAVED +NPY_FARRAY_RO = NPY_F_CONTIGUOUS | NPY_ALIGNED +NPY_DEFAULT = NPY_CARRAY +NPY_IN = NPY_CARRAY_RO +NPY_OUT = NPY_CARRAY +NPY_INOUT = NPY_CARRAY | NPY_UPDATEIFCOPY +NPY_IN_FARRAY = NPY_FARRAY_RO +NPY_OUT_FARRAY = NPY_FARRAY +NPY_INOUT_FARRAY = NPY_FARRAY | NPY_UPDATEIFCOPY +NPY_CONTIGUOUS = NPY_C_CONTIGUOUS | NPY_F_CONTIGUOUS +NPY_UPDATE_ALL = NPY_CONTIGUOUS | NPY_ALIGNED + + +# the asserts are needed, otherwise the translation fails + + at cpython_api([PyObject], rffi.INT_real, error=CANNOT_FAIL) +def _PyArray_Check(space, w_obj): + w_obj_type = space.type(w_obj) + w_type = space.gettypeobject(W_NDimArray.typedef) + return (space.is_w(w_obj_type, w_type) or + space.is_true(space.issubtype(w_obj_type, w_type))) + + at cpython_api([PyObject], rffi.INT_real, error=CANNOT_FAIL) +def _PyArray_CheckExact(space, w_obj): + w_obj_type = space.type(w_obj) + w_type = space.gettypeobject(W_NDimArray.typedef) + return space.is_w(w_obj_type, w_type) + + at cpython_api([PyObject], rffi.INT_real, error=CANNOT_FAIL) +def _PyArray_FLAGS(space, w_array): + assert isinstance(w_array, W_NDimArray) + flags = NPY_BEHAVED_NS + if isinstance(w_array.implementation, ConcreteArray): + flags |= NPY_OWNDATA + if len(w_array.get_shape()) < 2: + flags |= NPY_CONTIGUOUS + elif w_array.implementation.order == 'C': + flags |= NPY_C_CONTIGUOUS + else: + flags |= NPY_F_CONTIGUOUS + return flags + + at cpython_api([PyObject], rffi.INT_real, error=CANNOT_FAIL) +def _PyArray_NDIM(space, w_array): + assert isinstance(w_array, W_NDimArray) + return len(w_array.get_shape()) + + at cpython_api([PyObject, Py_ssize_t], Py_ssize_t, error=CANNOT_FAIL) +def _PyArray_DIM(space, w_array, n): + assert isinstance(w_array, W_NDimArray) + return w_array.get_shape()[n] + + at cpython_api([PyObject, Py_ssize_t], Py_ssize_t, error=CANNOT_FAIL) +def _PyArray_STRIDE(space, w_array, n): + assert isinstance(w_array, W_NDimArray) + return w_array.implementation.get_strides()[n] + + at cpython_api([PyObject], Py_ssize_t, error=CANNOT_FAIL) +def _PyArray_SIZE(space, w_array): + assert isinstance(w_array, W_NDimArray) + return w_array.get_size() + + at cpython_api([PyObject], rffi.INT_real, error=CANNOT_FAIL) +def _PyArray_ITEMSIZE(space, w_array): + assert isinstance(w_array, W_NDimArray) + return w_array.get_dtype().get_size() + + at cpython_api([PyObject], Py_ssize_t, error=CANNOT_FAIL) +def _PyArray_NBYTES(space, w_array): + assert isinstance(w_array, W_NDimArray) + return w_array.get_size() * w_array.get_dtype().get_size() + + at cpython_api([PyObject], rffi.INT_real, error=CANNOT_FAIL) +def _PyArray_TYPE(space, w_array): + assert isinstance(w_array, W_NDimArray) + return w_array.get_dtype().num + + + at cpython_api([PyObject], rffi.VOIDP, error=CANNOT_FAIL) +def _PyArray_DATA(space, w_array): + # fails on scalars - see PyArray_FromAny() + assert isinstance(w_array, W_NDimArray) + return rffi.cast(rffi.VOIDP, w_array.implementation.storage) + +PyArray_Descr = PyObject +NULL = lltype.nullptr(rffi.VOIDP.TO) + + at cpython_api([PyObject, PyArray_Descr, Py_ssize_t, Py_ssize_t, Py_ssize_t, rffi.VOIDP], + PyObject) +def _PyArray_FromAny(space, w_obj, w_dtype, min_depth, max_depth, requirements, context): + """ This is the main function used to obtain an array from any nested + sequence, or object that exposes the array interface, op. The + parameters allow specification of the required dtype, the + minimum (min_depth) and maximum (max_depth) number of dimensions + acceptable, and other requirements for the array. + + The dtype argument needs to be a PyArray_Descr structure indicating + the desired data-type (including required byteorder). The dtype + argument may be NULL, indicating that any data-type (and byteorder) + is acceptable. + Unless FORCECAST is present in flags, this call will generate an error + if the data type cannot be safely obtained from the object. If you + want to use NULL for the dtype and ensure the array is notswapped then + use PyArray_CheckFromAny. + + A value of 0 for either of the depth parameters causes the parameter + to be ignored. + + Any of the following array flags can be added (e.g. using |) to get + the requirements argument. If your code can handle general (e.g. + strided, byte-swapped, or unaligned arrays) then requirements + may be 0. Also, if op is not already an array (or does not expose + the array interface), then a new array will be created (and filled + from op using the sequence protocol). The new array will have + NPY_DEFAULT as its flags member. + + The context argument is passed to the __array__ method of op and is + only used if the array is constructed that way. Almost always this + parameter is NULL. + """ + if min_depth !=0 or max_depth != 0: + raise OperationError(space.w_NotImplementedError, space.wrap( + '_PyArray_FromAny called with not-implemented min_dpeth or max_depth argument')) + if requirements not in (0, NPY_DEFAULT): + raise OperationError(space.w_NotImplementedError, space.wrap( + '_PyArray_FromAny called with not-implemented requirements argument')) + w_array = array(space, w_obj, w_dtype=w_dtype, copy=False) + if w_array.is_scalar(): + # since PyArray_DATA() fails on scalars, create a 1D array and set empty + # shape. So the following combination works for *reading* scalars: + # PyObject *arr = PyArray_FromAny(obj); + # int nd = PyArray_NDIM(arr); + # void *data = PyArray_DATA(arr); + impl = w_array.implementation + w_array = W_NDimArray.from_shape(space, [1], impl.dtype) + w_array.implementation.setitem(0, impl.value) + w_array.implementation.shape = [] + return w_array + + at cpython_api([PyObject, Py_ssize_t, Py_ssize_t, Py_ssize_t], PyObject) +def _PyArray_FromObject(space, w_obj, typenum, min_depth, max_depth): + try: + dtype = get_dtype_cache(space).dtypes_by_num[typenum] + except KeyError: + raise OperationError(space.w_ValueError, space.wrap( + '_PyArray_FromObject called with invalid dtype %d' % typenum)) + try: + return _PyArray_FromAny(space, w_obj, dtype, min_depth, max_depth, + 0, NULL); + except OperationError, e: + if e.match(space, space.w_NotImplementedError): + errstr = space.str_w(e.get_w_value(space)) + errstr = '_PyArray_FromObject' + errstr[16:] + raise OperationError(space.w_NotImplementedError, space.wrap( + errstr)) + raise + +def get_shape_and_dtype(space, nd, dims, typenum): + shape = [] + for i in range(nd): + shape.append(rffi.cast(rffi.LONG, dims[i])) + dtype = get_dtype_cache(space).dtypes_by_num[typenum] + return shape, dtype + +def simple_new(space, nd, dims, typenum, + order='C', owning=False, w_subtype=None): + shape, dtype = get_shape_and_dtype(space, nd, dims, typenum) + return W_NDimArray.from_shape(space, shape, dtype) + +def simple_new_from_data(space, nd, dims, typenum, data, + order='C', owning=False, w_subtype=None): + shape, dtype = get_shape_and_dtype(space, nd, dims, typenum) + storage = rffi.cast(RAW_STORAGE_PTR, data) + if nd == 0: + w_val = dtype.itemtype.box_raw_data(storage) + return W_NDimArray(Scalar(dtype, w_val)) + else: + return W_NDimArray.from_shape_and_storage(space, shape, storage, dtype, + order=order, owning=owning, w_subtype=w_subtype) + + + at cpython_api([Py_ssize_t, rffi.LONGP, Py_ssize_t], PyObject) +def _PyArray_SimpleNew(space, nd, dims, typenum): + return simple_new(space, nd, dims, typenum) + + at cpython_api([Py_ssize_t, rffi.LONGP, Py_ssize_t, rffi.VOIDP], PyObject) +def _PyArray_SimpleNewFromData(space, nd, dims, typenum, data): + return simple_new_from_data(space, nd, dims, typenum, data, owning=False) + + at cpython_api([Py_ssize_t, rffi.LONGP, Py_ssize_t, rffi.VOIDP], PyObject) +def _PyArray_SimpleNewFromDataOwning(space, nd, dims, typenum, data): + # Variant to take over ownership of the memory, equivalent to: + # PyObject *arr = PyArray_SimpleNewFromData(nd, dims, typenum, data); + # ((PyArrayObject*)arr)->flags |= NPY_OWNDATA; + return simple_new_from_data(space, nd, dims, typenum, data, owning=True) + + + at cpython_api([rffi.VOIDP, Py_ssize_t, rffi.LONGP, Py_ssize_t, rffi.LONGP, + rffi.VOIDP, Py_ssize_t, Py_ssize_t, PyObject], PyObject) +def _PyArray_New(space, subtype, nd, dims, typenum, strides, data, itemsize, flags, obj): + if strides: + raise OperationError(space.w_NotImplementedError, + space.wrap("strides must be NULL")) + + order = 'C' if flags & NPY_C_CONTIGUOUS else 'F' + owning = True if flags & NPY_OWNDATA else False + w_subtype = None + + if data: + return simple_new_from_data(space, nd, dims, typenum, data, + order=order, owning=owning, w_subtype=w_subtype) + else: + return simple_new(space, nd, dims, typenum, + order=order, owning=owning, w_subtype=w_subtype) + diff --git a/pypy/module/cpyext/number.py b/pypy/module/cpyext/number.py --- a/pypy/module/cpyext/number.py +++ b/pypy/module/cpyext/number.py @@ -1,8 +1,9 @@ from pypy.interpreter.error import OperationError from pypy.module.cpyext.api import cpython_api, CANNOT_FAIL, Py_ssize_t -from pypy.module.cpyext.pyobject import PyObject +from pypy.module.cpyext.pyobject import PyObject, PyObjectP, from_ref, make_ref, Py_DecRef from rpython.rtyper.lltypesystem import rffi, lltype from rpython.tool.sourcetools import func_with_new_name +from pypy.module.cpyext.state import State @cpython_api([PyObject], rffi.INT_real, error=CANNOT_FAIL) def PyIndex_Check(space, w_obj): @@ -56,6 +57,39 @@ """ return space.index(w_obj) + at cpython_api([PyObjectP, PyObjectP], rffi.INT_real, error=CANNOT_FAIL) +def PyNumber_CoerceEx(space, pp1, pp2): + """This function is similar to PyNumber_Coerce(), except that it returns + 1 when the conversion is not possible and when no error is raised. + Reference counts are still not increased in this case.""" + retVal = PyNumber_Coerce(space, pp1, pp2) + if retVal != 0: + return 1 + return 0 + + at cpython_api([PyObjectP, PyObjectP], rffi.INT_real, error=CANNOT_FAIL) +def PyNumber_Coerce(space, pp1, pp2): + """This function takes the addresses of two variables of type PyObject*. If + the objects pointed to by *p1 and *p2 have the same type, increment their + reference count and return 0 (success). If the objects can be converted to a + common numeric type, replace *p1 and *p2 by their converted value (with + 'new' reference counts), and return 0. If no conversion is possible, or if + some other error occurs, return -1 (failure) and don't increment the + reference counts. The call PyNumber_Coerce(&o1, &o2) is equivalent to the + Python statement o1, o2 = coerce(o1, o2).""" + w_obj1 = from_ref(space, pp1[0]) + w_obj2 = from_ref(space, pp2[0]) + try: + w_res = space.coerce(w_obj1, w_obj2) + except (TypeError, OperationError): + state = space.fromcache(State) + state.clear_exception() + return -1 + w_res1, w_res2 = space.unpackiterable(w_res, 2) + pp1[0] = make_ref(space, w_res1) + pp2[0] = make_ref(space, w_res2) + return 0 + def func_rename(newname): return lambda func: func_with_new_name(func, newname) diff --git a/pypy/module/cpyext/src/missing.c b/pypy/module/cpyext/src/missing.c new file mode 100644 --- /dev/null +++ b/pypy/module/cpyext/src/missing.c @@ -0,0 +1,29 @@ +/* Definitions of missing symbols go here */ + +#include "Python.h" + +PyTypeObject PyFunction_Type; + +PyTypeObject PyMethod_Type; +PyTypeObject PyRange_Type; +PyTypeObject PyTraceBack_Type; + +int Py_DebugFlag = 1; +int Py_VerboseFlag = 0; +int Py_InteractiveFlag = 0; +int Py_InspectFlag = 0; +int Py_OptimizeFlag = 0; +int Py_NoSiteFlag = 0; +int Py_BytesWarningFlag = 0; +int Py_UseClassExceptionsFlag = 0; +int Py_FrozenFlag = 0; +int Py_TabcheckFlag = 0; +int Py_UnicodeFlag = 0; +int Py_IgnoreEnvironmentFlag = 0; +int Py_DivisionWarningFlag = 0; +int Py_DontWriteBytecodeFlag = 0; +int Py_NoUserSiteDirectory = 0; +int _Py_QnewFlag = 0; +int Py_Py3kWarningFlag = 0; +int Py_HashRandomizationFlag = 0; + diff --git a/pypy/module/cpyext/src/modsupport.c b/pypy/module/cpyext/src/modsupport.c --- a/pypy/module/cpyext/src/modsupport.c +++ b/pypy/module/cpyext/src/modsupport.c @@ -8,7 +8,9 @@ static PyObject *va_build_value(const char *, va_list, int); -/* Package context -- the full module name for package imports */ +/* Package context -- the full module name for package imports + * Should this be modified in _Py_InitPyPyModule for CPython + * compatibility (see CPython's Py_InitModule4)? */ char *_Py_PackageContext = NULL; /* Py_InitModule4() parameters: diff --git a/pypy/module/cpyext/src/ndarrayobject.c b/pypy/module/cpyext/src/ndarrayobject.c new file mode 100644 --- /dev/null +++ b/pypy/module/cpyext/src/ndarrayobject.c @@ -0,0 +1,27 @@ + +#include "Python.h" +#include "numpy/arrayobject.h" +#include /* memset, memcpy */ + +PyTypeObject PyArray_Type; + +void +_PyArray_FILLWBYTE(PyObject* obj, int val) { + memset(PyArray_DATA(obj), val, PyArray_NBYTES(obj)); +} + +PyObject* +_PyArray_ZEROS(int nd, npy_intp* dims, int type_num, int fortran) +{ + PyObject *arr = PyArray_EMPTY(nd, dims, type_num, fortran); + memset(PyArray_DATA(arr), 0, PyArray_NBYTES(arr)); + return arr; +} + +int +_PyArray_CopyInto(PyArrayObject* dest, PyArrayObject* src) +{ + memcpy(PyArray_DATA(dest), PyArray_DATA(src), PyArray_NBYTES(dest)); + return 0; +} + diff --git a/pypy/module/cpyext/stringobject.py b/pypy/module/cpyext/stringobject.py --- a/pypy/module/cpyext/stringobject.py +++ b/pypy/module/cpyext/stringobject.py @@ -275,7 +275,7 @@ Py_DecRef(space, string[0]) string[0] = make_ref(space, w_str) - at cpython_api([PyObject, rffi.CCHARP, rffi.CCHARP], PyObject) + at cpython_api([PyObject, CONST_STRING, CONST_STRING], PyObject) def PyString_AsEncodedObject(space, w_str, encoding, errors): """Encode a string object using the codec registered for encoding and return the result as Python object. encoding and errors have the same meaning as @@ -294,7 +294,7 @@ w_errors = space.wrap(rffi.charp2str(errors)) return space.call_method(w_str, 'encode', w_encoding, w_errors) - at cpython_api([PyObject, rffi.CCHARP, rffi.CCHARP], PyObject) + at cpython_api([PyObject, CONST_STRING, CONST_STRING], PyObject) def PyString_AsDecodedObject(space, w_str, encoding, errors): """Decode a string object by passing it to the codec registered for encoding and return the result as Python object. encoding and 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 @@ -1528,25 +1528,6 @@ """ raise NotImplementedError - at cpython_api([PyObjectP, PyObjectP], rffi.INT_real, error=-1) -def PyNumber_Coerce(space, p1, p2): - """This function takes the addresses of two variables of type PyObject*. If - the objects pointed to by *p1 and *p2 have the same type, increment their - reference count and return 0 (success). If the objects can be converted to a - common numeric type, replace *p1 and *p2 by their converted value (with - 'new' reference counts), and return 0. If no conversion is possible, or if - some other error occurs, return -1 (failure) and don't increment the - reference counts. The call PyNumber_Coerce(&o1, &o2) is equivalent to the - Python statement o1, o2 = coerce(o1, o2).""" - raise NotImplementedError - - at cpython_api([PyObjectP, PyObjectP], rffi.INT_real, error=-1) -def PyNumber_CoerceEx(space, p1, p2): - """This function is similar to PyNumber_Coerce(), except that it returns - 1 when the conversion is not possible and when no error is raised. - Reference counts are still not increased in this case.""" - raise NotImplementedError - @cpython_api([PyObject, rffi.INT_real], PyObject) def PyNumber_ToBase(space, n, base): """Returns the integer n converted to base as a string with a base diff --git a/pypy/module/cpyext/test/test_api.py b/pypy/module/cpyext/test/test_api.py --- a/pypy/module/cpyext/test/test_api.py +++ b/pypy/module/cpyext/test/test_api.py @@ -46,7 +46,7 @@ raise Exception("DID NOT RAISE") if getattr(space, 'w_' + expected_exc.__name__) is not operror.w_type: raise Exception("Wrong exception") - state.clear_exception() + return state.clear_exception() def setup_method(self, func): freeze_refcnts(self) diff --git a/pypy/module/cpyext/test/test_ndarrayobject.py b/pypy/module/cpyext/test/test_ndarrayobject.py new file mode 100644 --- /dev/null +++ b/pypy/module/cpyext/test/test_ndarrayobject.py @@ -0,0 +1,279 @@ +import py + +from pypy.module.cpyext.test.test_api import BaseApiTest +from pypy.module.cpyext.test.test_cpyext import AppTestCpythonExtensionBase +from rpython.rtyper.lltypesystem import rffi, lltype + +from pypy.module.micronumpy.interp_numarray import W_NDimArray +from pypy.module.micronumpy.interp_dtype import get_dtype_cache + +def scalar(space): + dtype = get_dtype_cache(space).w_float64dtype + return W_NDimArray.new_scalar(space, dtype, space.wrap(10.)) + +def array(space, shape, order='C'): + dtype = get_dtype_cache(space).w_float64dtype + return W_NDimArray.from_shape(space, shape, dtype, order=order) + +def iarray(space, shape, order='C'): + dtype = get_dtype_cache(space).w_int64dtype + return W_NDimArray.from_shape(space, shape, dtype, order=order) + + +NULL = lltype.nullptr(rffi.VOIDP.TO) + +class TestNDArrayObject(BaseApiTest): + + def test_Check(self, space, api): + a = array(space, [10, 5, 3]) + x = space.wrap(10.) + assert api._PyArray_Check(a) + assert api._PyArray_CheckExact(a) + assert not api._PyArray_Check(x) + assert not api._PyArray_CheckExact(x) + + def test_FLAGS(self, space, api): + s = array(space, [10]) + c = array(space, [10, 5, 3], order='C') + f = array(space, [10, 5, 3], order='F') + assert api._PyArray_FLAGS(s) & 0x0001 + assert api._PyArray_FLAGS(s) & 0x0002 + assert api._PyArray_FLAGS(c) & 0x0001 + assert api._PyArray_FLAGS(f) & 0x0002 + assert not api._PyArray_FLAGS(c) & 0x0002 + assert not api._PyArray_FLAGS(f) & 0x0001 + + def test_NDIM(self, space, api): + a = array(space, [10, 5, 3]) + assert api._PyArray_NDIM(a) == 3 + + def test_DIM(self, space, api): + a = array(space, [10, 5, 3]) + assert api._PyArray_DIM(a, 1) == 5 + + def test_STRIDE(self, space, api): + a = array(space, [10, 5, 3], ) + assert api._PyArray_STRIDE(a, 1) == a.implementation.get_strides()[1] + + def test_SIZE(self, space, api): + a = array(space, [10, 5, 3]) + assert api._PyArray_SIZE(a) == 150 + + def test_ITEMSIZE(self, space, api): + a = array(space, [10, 5, 3]) + assert api._PyArray_ITEMSIZE(a) == 8 + + def test_NBYTES(self, space, api): + a = array(space, [10, 5, 3]) + assert api._PyArray_NBYTES(a) == 1200 + + def test_TYPE(self, space, api): + a = array(space, [10, 5, 3]) + assert api._PyArray_TYPE(a) == 12 + + def test_DATA(self, space, api): + a = array(space, [10, 5, 3]) + addr = api._PyArray_DATA(a) + addr2 = rffi.cast(rffi.VOIDP, a.implementation.storage) + assert addr == addr2 + + def test_FromAny_scalar(self, space, api): + a0 = scalar(space) + assert a0.implementation.get_scalar_value().value == 10. + + a = api._PyArray_FromAny(a0, NULL, 0, 0, 0, NULL) + assert api._PyArray_NDIM(a) == 0 + + ptr = rffi.cast(rffi.DOUBLEP, api._PyArray_DATA(a)) + assert ptr[0] == 10. + + def test_FromAny(self, space, api): + a = array(space, [10, 5, 3]) + assert api._PyArray_FromAny(a, NULL, 0, 0, 0, NULL) is a + self.raises(space, api, NotImplementedError, api._PyArray_FromAny, + a, NULL, 0, 3, 0, NULL) + + def test_FromObject(self, space, api): + a = array(space, [10, 5, 3]) + assert api._PyArray_FromObject(a, a.get_dtype().num, 0, 0) is a + exc = self.raises(space, api, NotImplementedError, api._PyArray_FromObject, + a, 11, 0, 3) + assert exc.errorstr(space).find('FromObject') >= 0 + + def test_list_from_fixedptr(self, space, api): + A = lltype.GcArray(lltype.Float) + ptr = lltype.malloc(A, 3) + assert isinstance(ptr, lltype._ptr) + ptr[0] = 10. + ptr[1] = 5. + ptr[2] = 3. + l = list(ptr) + assert l == [10., 5., 3.] + + def test_list_from_openptr(self, space, api): + nd = 3 + a = array(space, [nd]) + ptr = rffi.cast(rffi.DOUBLEP, api._PyArray_DATA(a)) + ptr[0] = 10. + ptr[1] = 5. + ptr[2] = 3. + l = [] + for i in range(nd): + l.append(ptr[i]) + assert l == [10., 5., 3.] + + def test_SimpleNew_scalar(self, space, api): + ptr_s = lltype.nullptr(rffi.LONGP.TO) + a = api._PyArray_SimpleNew(0, ptr_s, 12) + + dtype = get_dtype_cache(space).w_float64dtype + + a.set_scalar_value(dtype.itemtype.box(10.)) + assert a.get_scalar_value().value == 10. + + def test_SimpleNewFromData_scalar(self, space, api): + a = array(space, [1]) + num = api._PyArray_TYPE(a) + ptr_a = api._PyArray_DATA(a) + + x = rffi.cast(rffi.DOUBLEP, ptr_a) + x[0] = float(10.) + + ptr_s = lltype.nullptr(rffi.LONGP.TO) + + res = api._PyArray_SimpleNewFromData(0, ptr_s, num, ptr_a) + assert res.is_scalar() + assert res.get_scalar_value().value == 10. + + def test_SimpleNew(self, space, api): + shape = [10, 5, 3] + nd = len(shape) + + s = iarray(space, [nd]) + ptr_s = rffi.cast(rffi.LONGP, api._PyArray_DATA(s)) + ptr_s[0] = 10 + ptr_s[1] = 5 + ptr_s[2] = 3 + + a = api._PyArray_SimpleNew(nd, ptr_s, 12) + + #assert list(api._PyArray_DIMS(a))[:3] == shape + + ptr_a = api._PyArray_DATA(a) + + x = rffi.cast(rffi.DOUBLEP, ptr_a) + for i in range(150): + x[i] = float(i) + + for i in range(150): + assert x[i] == float(i) + + def test_SimpleNewFromData(self, space, api): + shape = [10, 5, 3] + nd = len(shape) + + s = iarray(space, [nd]) + ptr_s = rffi.cast(rffi.LONGP, api._PyArray_DATA(s)) + ptr_s[0] = 10 + ptr_s[1] = 5 + ptr_s[2] = 3 + + a = array(space, shape) + num = api._PyArray_TYPE(a) + ptr_a = api._PyArray_DATA(a) + + x = rffi.cast(rffi.DOUBLEP, ptr_a) + for i in range(150): + x[i] = float(i) + + res = api._PyArray_SimpleNewFromData(nd, ptr_s, num, ptr_a) + assert api._PyArray_TYPE(res) == num + assert api._PyArray_DATA(res) == ptr_a + for i in range(nd): + assert api._PyArray_DIM(res, i) == shape[i] + ptr_r = rffi.cast(rffi.DOUBLEP, api._PyArray_DATA(res)) + for i in range(150): + assert ptr_r[i] == float(i) + res = api._PyArray_SimpleNewFromDataOwning(nd, ptr_s, num, ptr_a) + x = rffi.cast(rffi.DOUBLEP, ptr_a) + ptr_r = rffi.cast(rffi.DOUBLEP, api._PyArray_DATA(res)) + x[20] = -100. + assert ptr_r[20] == -100. + + def test_SimpleNewFromData_complex(self, space, api): + a = array(space, [2]) + ptr_a = api._PyArray_DATA(a) + + x = rffi.cast(rffi.DOUBLEP, ptr_a) + x[0] = 3. + x[1] = 4. + + ptr_s = lltype.nullptr(rffi.LONGP.TO) + + res = api._PyArray_SimpleNewFromData(0, ptr_s, 15, ptr_a) + assert res.get_scalar_value().real == 3. + assert res.get_scalar_value().imag == 4. + +class AppTestCNumber(AppTestCpythonExtensionBase): + def test_ndarray_object_c(self): + mod = self.import_extension('foo', [ + ("test_simplenew", "METH_NOARGS", + ''' + npy_intp dims[2] ={2, 3}; + PyObject * obj = PyArray_SimpleNew(2, dims, 11); + return obj; + ''' + ), + ("test_fill", "METH_NOARGS", + ''' + npy_intp dims[2] ={2, 3}; + PyObject * obj = PyArray_SimpleNew(2, dims, 1); + PyArray_FILLWBYTE(obj, 42); + return obj; + ''' + ), + ("test_copy", "METH_NOARGS", + ''' + npy_intp dims1[2] ={2, 3}; + npy_intp dims2[2] ={3, 2}; + PyObject * obj1 = PyArray_ZEROS(2, dims1, 11, 0); + PyObject * obj2 = PyArray_ZEROS(2, dims2, 11, 0); + PyArray_FILLWBYTE(obj2, 42); + PyArray_CopyInto(obj2, obj1); + Py_DECREF(obj1); + return obj2; + ''' + ), + ("test_FromAny", "METH_NOARGS", + ''' + npy_intp dims[2] ={2, 3}; + PyObject * obj1 = PyArray_SimpleNew(2, dims, 1); + PyArray_FILLWBYTE(obj1, 42); + PyObject * obj2 = _PyArray_FromAny(obj1, NULL, 0, 0, 0, NULL); + Py_DECREF(obj1); + return obj2; + ''' + ), + ("test_FromObject", "METH_NOARGS", + ''' + npy_intp dims[2] ={2, 3}; + PyObject * obj1 = PyArray_SimpleNew(2, dims, 1); + PyArray_FILLWBYTE(obj1, 42); + PyObject * obj2 = _PyArray_FromObject(obj1, 12, 0, 0); + Py_DECREF(obj1); + return obj2; + ''' + ), + ], prologue='#include ') + arr = mod.test_simplenew() + assert arr.shape == (2, 3) + assert arr.dtype.num == 11 #float32 dtype + arr = mod.test_fill() + assert arr.shape == (2, 3) + assert arr.dtype.num == 1 #int8 dtype + assert (arr == 42).all() + arr = mod.test_copy() + assert (arr == 0).all() + #Make sure these work without errors + arr = mod.test_FromAny() + arr = mod.test_FromObject() diff --git a/pypy/module/cpyext/test/test_number.py b/pypy/module/cpyext/test/test_number.py --- a/pypy/module/cpyext/test/test_number.py +++ b/pypy/module/cpyext/test/test_number.py @@ -1,7 +1,7 @@ -from rpython.rtyper.lltypesystem import rffi, lltype -from pypy.interpreter.error import OperationError +from rpython.rtyper.lltypesystem import lltype from pypy.module.cpyext.test.test_api import BaseApiTest -from pypy.module.cpyext import sequence +from pypy.module.cpyext.pyobject import PyObjectP, from_ref, make_ref, Py_DecRef +from pypy.module.cpyext.test.test_cpyext import AppTestCpythonExtensionBase class TestIterator(BaseApiTest): def test_check(self, space, api): @@ -39,6 +39,46 @@ assert w_l is None api.PyErr_Clear() + def test_coerce(self, space, api): + w_obj1 = space.wrap(123) + w_obj2 = space.wrap(456.789) + pp1 = lltype.malloc(PyObjectP.TO, 1, flavor='raw') + pp1[0] = make_ref(space, w_obj1) + pp2 = lltype.malloc(PyObjectP.TO, 1, flavor='raw') + pp2[0] = make_ref(space, w_obj2) + assert api.PyNumber_Coerce(pp1, pp2) == 0 + assert space.str_w(space.repr(from_ref(space, pp1[0]))) == '123.0' + assert space.str_w(space.repr(from_ref(space, pp2[0]))) == '456.789' + Py_DecRef(space, pp1[0]) + Py_DecRef(space, pp2[0]) + lltype.free(pp1, flavor='raw') + # Yes, decrement twice since we decoupled between w_obj* and pp*[0]. + Py_DecRef(space, w_obj1) + Py_DecRef(space, w_obj2) + lltype.free(pp2, flavor='raw') + + def test_number_coerce_ex(self, space, api): + pl = make_ref(space, space.wrap(123)) + pf = make_ref(space, space.wrap(42.)) + ppl = lltype.malloc(PyObjectP.TO, 1, flavor='raw') + ppf = lltype.malloc(PyObjectP.TO, 1, flavor='raw') + ppl[0] = pl + ppf[0] = pf + + ret = api.PyNumber_CoerceEx(ppl, ppf) + assert ret == 0 + + w_res = from_ref(space, ppl[0]) + + assert api.PyFloat_Check(w_res) + assert space.unwrap(w_res) == 123. + Py_DecRef(space, pl) + Py_DecRef(space, pf) + Py_DecRef(space, ppl[0]) + Py_DecRef(space, ppf[0]) + lltype.free(ppl, flavor='raw') + lltype.free(ppf, flavor='raw') + def test_numbermethods(self, space, api): assert "ab" == space.unwrap( api.PyNumber_Add(space.wrap("a"), space.wrap("b"))) @@ -64,3 +104,40 @@ api.PyNumber_Power(space.wrap(3), space.wrap(2), space.wrap(5))) assert 9 == space.unwrap( api.PyNumber_InPlacePower(space.wrap(3), space.wrap(2), space.w_None)) + +class AppTestCNumber(AppTestCpythonExtensionBase): + def test_app_coerce(self): + mod = self.import_extension('foo', [ + ("test_fail", "METH_NOARGS", + ''' + PyObject * hello = PyString_FromString("hello"); + PyObject * float1 = PyFloat_FromDouble(1.0); + int retVal = PyNumber_Coerce(&hello, &float1); + Py_DECREF(hello); + Py_DECREF(float1); + return PyInt_FromLong(retVal); + '''), + ("test", "METH_NOARGS", + ''' + PyObject * float1p = PyFloat_FromDouble(1.0); + PyObject * int3p = PyInt_FromLong(3); + PyObject * tupl = PyTuple_New(2); + PyObject float1 = *float1p; + PyObject int3 = *int3p; + int retVal = PyNumber_CoerceEx(&int3p, &float1p); + if (retVal == 0) + { + PyTuple_SET_ITEM(tupl, 0, int3p); + PyTuple_SET_ITEM(tupl, 1, float1p); + } + Py_DECREF(&int3); + Py_DECREF(&float1); + Py_DECREF(int3p); + Py_DECREF(float1p); + return tupl; + ''')]) + assert mod.test_fail() == -1 + '''tupl = mod.test() + assert tupl[0] == 3. + assert tupl[1] == 1. + assert isinstance(tupl[0], float)''' diff --git a/pypy/module/cpyext/test/test_ztranslation.py b/pypy/module/cpyext/test/test_ztranslation.py new file mode 100644 --- /dev/null +++ b/pypy/module/cpyext/test/test_ztranslation.py @@ -0,0 +1,4 @@ +from pypy.objspace.fake.checkmodule import checkmodule + +def test_cpyext_translates(): + checkmodule('cpyext', '_ffi') 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, backward_broadcast=False): + def create_iter(self, shape=None, backward_broadcast=False, require_index=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 @@ -279,6 +279,16 @@ return W_NDimArray.new_slice(space, self.start, strides, backstrides, shape, self, orig_arr) + def nonzero(self, space, index_type): + s = loop.count_all_true_concrete(self) + box = index_type.itemtype.box + nd = len(self.get_shape()) + w_res = W_NDimArray.from_shape(space, [s, nd], index_type) + loop.nonzero(w_res, self, box) + w_res = w_res.implementation.swapaxes(space, w_res, 0, 1) + l_w = [w_res.descr_getitem(space, space.wrap(d)) for d in range(nd)] + return space.newtuple(l_w) + def get_storage_as_int(self, space): return rffi.cast(lltype.Signed, self.storage) + self.start @@ -315,14 +325,23 @@ self.backstrides = backstrides self.storage = storage - def create_iter(self, shape=None, backward_broadcast=False): - if shape is None or \ - support.product(shape) <= support.product(self.get_shape()): + def create_iter(self, shape=None, backward_broadcast=False, require_index=False): + if shape is not None and \ + support.product(shape) > support.product(self.get_shape()): + r = calculate_broadcast_strides(self.get_strides(), + self.get_backstrides(), + self.get_shape(), shape, backward_broadcast) + return iter.MultiDimViewIterator(self, self.dtype, self.start, r[0], r[1], shape) + + if not require_index: return iter.ConcreteArrayIterator(self) - r = calculate_broadcast_strides(self.get_strides(), - self.get_backstrides(), - self.get_shape(), shape, backward_broadcast) - return iter.MultiDimViewIterator(self, self.dtype, 0, r[0], r[1], shape) + else: + if len(self.get_shape()) == 1: + return iter.OneDimViewIterator(self, self.dtype, self.start, + self.get_strides(), self.get_shape()) + else: + return iter.MultiDimViewIterator(self, self.dtype, self.start, + self.get_strides(), self.get_backstrides(), self.get_shape()) def fill(self, box): self.dtype.fill(self.storage, box, 0, self.size) @@ -385,9 +404,9 @@ def fill(self, box): loop.fill(self, box.convert_to(self.dtype)) - def create_iter(self, shape=None, backward_broadcast=False): - if shape is not None and shape != self.get_shape() and \ - support.product(shape) > support.product(self.get_shape()): + def create_iter(self, shape=None, backward_broadcast=False, require_index=False): + if shape is not None and \ + support.product(shape) > support.product(self.get_shape()): r = calculate_broadcast_strides(self.get_strides(), self.get_backstrides(), self.get_shape(), shape, 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 @@ -45,7 +45,7 @@ def get_backstrides(self): return [] - def create_iter(self, shape=None, backward_broadcast=False): + def create_iter(self, shape=None, backward_broadcast=False, require_index=False): return ScalarIterator(self) def get_scalar_value(self): @@ -155,6 +155,13 @@ def swapaxes(self, space, orig_array, axis1, axis2): raise Exception("should not be called") + def nonzero(self, space, index_type): + s = self.dtype.itemtype.bool(self.value) + w_res = W_NDimArray.from_shape(space, [s], index_type) + if s == 1: + w_res.implementation.setitem(0, index_type.itemtype.box(0)) + return space.newtuple([w_res]) + def fill(self, w_value): self.value = w_value 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,4 +1,5 @@ +from pypy.interpreter.error import OperationError from pypy.interpreter.baseobjspace import W_Root from rpython.tool.pairtype import extendabletype from pypy.module.micronumpy.support import calc_strides @@ -86,15 +87,26 @@ def convert_to_array(space, w_obj): + #XXX: This whole routine should very likely simply be array() 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): - # Convert to array. - return array(space, w_obj, w_order=None) else: - # If it's a scalar - dtype = interp_ufuncs.find_dtype_for_scalar(space, w_obj) - return W_NDimArray.new_scalar(space, dtype, w_obj) + # Use __array__() method if it exists + w_array = space.lookup(w_obj, "__array__") + if w_array is not None: + w_result = space.get_and_call_function(w_array, w_obj) + if isinstance(w_result, W_NDimArray): + return w_result + else: + raise OperationError(space.w_ValueError, + space.wrap("object __array__ method not producing an array")) + elif issequence_w(space, w_obj): + # Convert to array. + return array(space, w_obj, w_order=None) + else: + # If it's a scalar + dtype = interp_ufuncs.find_dtype_for_scalar(space, w_obj) + return W_NDimArray.new_scalar(space, dtype, w_obj) diff --git a/pypy/module/micronumpy/compile.py b/pypy/module/micronumpy/compile.py --- a/pypy/module/micronumpy/compile.py +++ b/pypy/module/micronumpy/compile.py @@ -47,6 +47,9 @@ def __init__(self, name): self.name = name + def lookup(self, name): + return self.getdictvalue(self, name) + class FakeSpace(object): w_ValueError = W_TypeObject("ValueError") w_TypeError = W_TypeObject("TypeError") @@ -204,6 +207,10 @@ return W_NDimArray return self.w_None + def lookup(self, w_obj, name): + w_type = self.type(w_obj) + return w_type.lookup(name) + def gettypefor(self, w_obj): return None 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 @@ -804,11 +804,6 @@ self.dtypes_by_name[alias] = dtype self.dtypes_by_name[dtype.char] = dtype - self.dtypes_by_num = [dtype for dtype in - sorted(self.dtypes_by_num.values(), key=lambda dtype: dtype.num) - if dtype.num <= self.w_float64dtype.num] - assert len(self.dtypes_by_num) == self.w_float64dtype.num + 1 - typeinfo_full = { 'LONGLONG': self.w_int64dtype, 'SHORT': self.w_int16dtype, 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, backward_broadcast=False): + def create_iter(self, shape=None, backward_broadcast=False, require_index=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 @@ -5,7 +5,7 @@ from pypy.module.micronumpy.base import W_NDimArray, convert_to_array,\ ArrayArgumentException, issequence_w, wrap_impl from pypy.module.micronumpy import interp_dtype, interp_ufuncs, interp_boxes,\ - interp_arrayops + interp_arrayops, iter from pypy.module.micronumpy.strides import find_shape_and_elems,\ get_shape_from_iterable, to_coords, shape_agreement, \ shape_agreement_multiple @@ -95,8 +95,7 @@ if idx.get_size() > self.get_size(): raise OperationError(space.w_ValueError, space.wrap("index out of range for array")) - idx_iter = idx.create_iter() - size = loop.count_all_true_iter(idx_iter, idx.get_shape(), idx.get_dtype()) + size = loop.count_all_true(idx) if size > val.get_size() and val.get_size() > 1: raise OperationError(space.w_ValueError, space.wrap("NumPy boolean array indexing assignment " "cannot assign %d input values to " @@ -238,10 +237,11 @@ s.append('])') return s.build() - def create_iter(self, shape=None, backward_broadcast=False): + def create_iter(self, shape=None, backward_broadcast=False, require_index=False): assert isinstance(self.implementation, BaseArrayImplementation) return self.implementation.create_iter(shape=shape, - backward_broadcast=backward_broadcast) + backward_broadcast=backward_broadcast, + require_index=require_index) def create_axis_iter(self, shape, dim, cum): return self.implementation.create_axis_iter(shape, dim, cum) @@ -340,6 +340,10 @@ return self return self.implementation.swapaxes(space, self, axis1, axis2) + def descr_nonzero(self, space): + index_type = interp_dtype.get_dtype_cache(space).w_int64dtype + return self.implementation.nonzero(space, index_type) + def descr_tolist(self, space): if len(self.get_shape()) == 0: return self.get_scalar_value().item(space) @@ -426,6 +430,13 @@ raise OperationError(space.w_NotImplementedError, space.wrap( "non-int arg not supported")) + def descr___array__(self, space, w_dtype=None): + if not space.is_none(w_dtype): + raise OperationError(space.w_NotImplementedError, space.wrap( + "__array__(dtype) not implemented")) + # stub implementation of __array__() + return self + def descr_array_iface(self, space): addr = self.implementation.get_storage_as_int(space) # will explode if it can't @@ -695,7 +706,7 @@ descr_conj = _unaryop_impl('conjugate') - def descr_nonzero(self, space): + def descr___nonzero__(self, space): if self.get_size() > 1: raise OperationError(space.w_ValueError, space.wrap( "The truth value of an array with more than one element is ambiguous. Use a.any() or a.all()")) @@ -1004,7 +1015,7 @@ __neg__ = interp2app(W_NDimArray.descr_neg), __abs__ = interp2app(W_NDimArray.descr_abs), __invert__ = interp2app(W_NDimArray.descr_invert), - __nonzero__ = interp2app(W_NDimArray.descr_nonzero), + __nonzero__ = interp2app(W_NDimArray.descr___nonzero__), __add__ = interp2app(W_NDimArray.descr_add), __sub__ = interp2app(W_NDimArray.descr_sub), @@ -1097,6 +1108,7 @@ compress = interp2app(W_NDimArray.descr_compress), repeat = interp2app(W_NDimArray.descr_repeat), swapaxes = interp2app(W_NDimArray.descr_swapaxes), + nonzero = interp2app(W_NDimArray.descr_nonzero), flat = GetSetProperty(W_NDimArray.descr_get_flatiter), item = interp2app(W_NDimArray.descr_item), real = GetSetProperty(W_NDimArray.descr_get_real, @@ -1127,18 +1139,36 @@ __reduce__ = interp2app(W_NDimArray.descr_reduce), __setstate__ = interp2app(W_NDimArray.descr_setstate), __array_finalize__ = interp2app(W_NDimArray.descr___array_finalize__), + + __array__ = interp2app(W_NDimArray.descr___array__), ) @unwrap_spec(ndmin=int, copy=bool, subok=bool) def array(space, w_object, w_dtype=None, copy=True, w_order=None, subok=False, ndmin=0): + # for anything that isn't already an array, try __array__ method first + if not isinstance(w_object, W_NDimArray): + w___array__ = space.lookup(w_object, "__array__") + if w___array__ is not None: + if space.is_none(w_dtype): + w_dtype = space.w_None + w_array = space.get_and_call_function(w___array__, w_object, w_dtype) + if isinstance(w_array, W_NDimArray): + # feed w_array back into array() for other properties + return array(space, w_array, w_dtype, False, w_order, subok, ndmin) + else: + raise operationerrfmt(space.w_ValueError, + "object __array__ method not producing an array") + + # scalars and strings w/o __array__ method isstr = space.isinstance_w(w_object, space.w_str) if not issequence_w(space, w_object) or isstr: if space.is_none(w_dtype) or isstr: w_dtype = interp_ufuncs.find_dtype_for_scalar(space, w_object) dtype = space.interp_w(interp_dtype.W_Dtype, - space.call_function(space.gettypefor(interp_dtype.W_Dtype), w_dtype)) + space.call_function(space.gettypefor(interp_dtype.W_Dtype), w_dtype)) return W_NDimArray.new_scalar(space, dtype, w_object) + if space.is_none(w_order): order = 'C' else: @@ -1147,6 +1177,7 @@ raise operationerrfmt(space.w_ValueError, "Unknown order: %s", order) + # arrays with correct dtype dtype = interp_dtype.decode_w_dtype(space, w_dtype) if isinstance(w_object, W_NDimArray) and \ (space.is_none(w_dtype) or w_object.get_dtype() is dtype): @@ -1163,6 +1194,8 @@ w_ret.implementation = w_ret.implementation.set_shape(space, w_ret, shape) return w_ret + + # not an array or incorrect dtype shape, elems_w = find_shape_and_elems(space, w_object, dtype) if dtype is None or ( dtype.is_str_or_unicode() and dtype.itemtype.get_size() < 1): diff --git a/pypy/module/micronumpy/iter.py b/pypy/module/micronumpy/iter.py --- a/pypy/module/micronumpy/iter.py +++ b/pypy/module/micronumpy/iter.py @@ -215,6 +215,9 @@ def reset(self): self.offset %= self.size + def get_index(self, d): + return self.index + class MultiDimViewIterator(ConcreteArrayIterator): ''' The view iterator dtype can be different from the array.dtype, this is what makes it a View @@ -268,6 +271,9 @@ def reset(self): self.offset %= self.size + def get_index(self, d): + return self.indexes[d] + class AxisIterator(base.BaseArrayIterator): def __init__(self, array, shape, dim, cumultative): self.shape = shape 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,25 +318,45 @@ lefti.next() return result +count_all_true_driver = jit.JitDriver(name = 'numpy_count', + greens = ['shapelen', 'dtype'], + reds = 'auto') + +def count_all_true_concrete(impl): + s = 0 + iter = impl.create_iter() + shapelen = len(impl.shape) + dtype = impl.dtype + while not iter.done(): + count_all_true_driver.jit_merge_point(shapelen=shapelen, dtype=dtype) + s += iter.getitem_bool() From noreply at buildbot.pypy.org Mon Sep 23 08:53:44 2013 From: noreply at buildbot.pypy.org (mattip) Date: Mon, 23 Sep 2013 08:53:44 +0200 (CEST) Subject: [pypy-commit] pypy default: add text to numpy comparison page, hopefully make it easier for google to find Message-ID: <20130923065344.07DC01C013B@cobra.cs.uni-duesseldorf.de> Author: Matti Picus Branch: Changeset: r67065:aa4e8c5cb4af Date: 2013-09-23 09:01 +0300 http://bitbucket.org/pypy/pypy/changeset/aa4e8c5cb4af/ Log: add text to numpy comparison page, hopefully make it easier for google to find diff --git a/pypy/module/micronumpy/tool/numready/page.html b/pypy/module/micronumpy/tool/numready/page.html --- a/pypy/module/micronumpy/tool/numready/page.html +++ b/pypy/module/micronumpy/tool/numready/page.html @@ -3,9 +3,11 @@ NumPyPy Status + -

    NumPyPy Status

    +

    NumPyPy Status: how much of numpy can you use in pypy?

    Version: {{ ver }}

    +

    numpy compatability test results, generated automatically by running
    + pypy/module/micronumpy/tool/numready/main.py <path-to-latest-pypy>

    Overall: {{ msg }}

    From noreply at buildbot.pypy.org Mon Sep 23 09:04:16 2013 From: noreply at buildbot.pypy.org (arigo) Date: Mon, 23 Sep 2013 09:04:16 +0200 (CEST) Subject: [pypy-commit] pypy default: More standard html Message-ID: <20130923070416.84BD81C013B@cobra.cs.uni-duesseldorf.de> Author: Armin Rigo Branch: Changeset: r67069:eb812b3eb381 Date: 2013-09-23 09:03 +0200 http://bitbucket.org/pypy/pypy/changeset/eb812b3eb381/ Log: More standard html diff --git a/pypy/module/micronumpy/tool/numready/page.html b/pypy/module/micronumpy/tool/numready/page.html --- a/pypy/module/micronumpy/tool/numready/page.html +++ b/pypy/module/micronumpy/tool/numready/page.html @@ -38,7 +38,7 @@

    NumPyPy Status: how much of numpy can you use in pypy?

    Version: {{ ver }}

    numpy compatability test results, generated automatically by running
    - pypy/module/micronumpy/tool/numready/main.py <path-to-latest-pypy>

    + pypy/module/micronumpy/tool/numready/main.py <path-to-latest-pypy>

    Overall: {{ msg }}

    From noreply at buildbot.pypy.org Mon Sep 23 09:58:25 2013 From: noreply at buildbot.pypy.org (bivab) Date: Mon, 23 Sep 2013 09:58:25 +0200 (CEST) Subject: [pypy-commit] pypy default: document how to update the list of contributors Message-ID: <20130923075825.3D41E1C1007@cobra.cs.uni-duesseldorf.de> Author: David Schneider Branch: Changeset: r67070:2a9e0a20da94 Date: 2013-09-23 09:57 +0200 http://bitbucket.org/pypy/pypy/changeset/2a9e0a20da94/ Log: document how to update the list of contributors diff --git a/pypy/doc/how-to-release.rst b/pypy/doc/how-to-release.rst --- a/pypy/doc/how-to-release.rst +++ b/pypy/doc/how-to-release.rst @@ -25,6 +25,7 @@ necessary; also update the version number in pypy/doc/conf.py, and in pypy/doc/index.rst * update pypy/doc/contributor.rst (and possibly LICENSE) + pypy/doc/tool/makecontributor.py generates the list of contributors * rename pypy/doc/whatsnew_head.rst to whatsnew_VERSION.rst and create a fresh whatsnew_head.rst after the release * update README From noreply at buildbot.pypy.org Mon Sep 23 17:15:14 2013 From: noreply at buildbot.pypy.org (arigo) Date: Mon, 23 Sep 2013 17:15:14 +0200 (CEST) Subject: [pypy-commit] stmgc default: in-progress: API for the pypy jit, with support for a custom Message-ID: <20130923151514.72EB51C34C9@cobra.cs.uni-duesseldorf.de> Author: Armin Rigo Branch: Changeset: r531:0581363bf46a Date: 2013-09-23 17:14 +0200 http://bitbucket.org/pypy/stmgc/changeset/0581363bf46a/ Log: in-progress: API for the pypy jit, with support for a custom implementation of setjmp/longjmp. diff --git a/c4/et.c b/c4/et.c --- a/c4/et.c +++ b/c4/et.c @@ -1016,7 +1016,12 @@ // jump back to the setjmp_buf (this call does not return) stm_stop_sharedlock(); - longjmp(*d->setjmp_buf, 1); + if (d->longjmp_callback != NULL) + d->longjmp_callback(d->setjmp_buf); + else + longjmp(*(jmp_buf *)d->setjmp_buf, 1); + + stm_fatalerror("longjmp() call should not return"); } void AbortTransactionAfterCollect(struct tx_descriptor *d, int reason) @@ -1083,12 +1088,13 @@ gcptrlist_clear(&d->abortinfo); } -void BeginTransaction(jmp_buf* buf) +void stm_begin_transaction(void *buf, void (*longjmp_callback)(void *)) { struct tx_descriptor *d = thread_descriptor; init_transaction(d); d->active = 1; d->setjmp_buf = buf; + d->longjmp_callback = longjmp_callback; d->old_thread_local_obj = stm_thread_local_obj; d->start_time = GetGlobalCurTime(d); update_reads_size_limit(d); diff --git a/c4/et.h b/c4/et.h --- a/c4/et.h +++ b/c4/et.h @@ -159,7 +159,8 @@ struct tx_descriptor { struct tx_public_descriptor *public_descriptor; revision_t public_descriptor_index; - jmp_buf *setjmp_buf; + void *setjmp_buf; + void(*longjmp_callback)(void *); revision_t start_time; revision_t my_lock; gcptr *shadowstack; @@ -205,7 +206,6 @@ /************************************************************/ -void BeginTransaction(jmp_buf *); void BeginInevitableTransaction(void); /* must save roots around this call */ void CommitTransaction(void); /* must save roots around this call */ void BecomeInevitable(const char *why); /* must save roots around this call */ diff --git a/c4/stmgc.h b/c4/stmgc.h --- a/c4/stmgc.h +++ b/c4/stmgc.h @@ -121,6 +121,12 @@ void stm_begin_inevitable_transaction(void); void stm_become_inevitable(const char *reason); +/* specialized usage: for custom setjmp/longjmp implementation. + Must save roots around calls. */ +void stm_begin_transaction(void *buf, void (*longjmp_callback)(void *)); +void stm_transaction_break(void *buf, void (*longjmp_callback)(void *)); +void stm_invalidate_jmp_buf(void *buf); + /* debugging: check if we're currently running a transaction or not. */ int stm_in_transaction(void); diff --git a/c4/stmsync.c b/c4/stmsync.c --- a/c4/stmsync.c +++ b/c4/stmsync.c @@ -176,7 +176,7 @@ d->reads_size_limit_nonatomic = limit; } if (!d->atomic) { - BeginTransaction(&_jmpbuf); + stm_begin_transaction(&_jmpbuf, NULL); } else { /* atomic transaction: a common case is that callback() returned @@ -213,6 +213,35 @@ assert(stm_shadowstack == v_saved_value); } +void stm_transaction_break(void *buf, void (*longjmp_callback)(void *)) +{ /* must save roots around this call */ + struct tx_descriptor *d = thread_descriptor; + if (d->atomic) { + assert(d->active >= 1); + stm_possible_safe_point(); + } + else { + CommitTransaction(); + if (d->active != 2) { + unsigned long limit = d->reads_size_limit_nonatomic; + if (limit != 0 && limit < (stm_regular_length_limit >> 1)) + limit = (limit << 1) | 1; + else + limit = stm_regular_length_limit; + d->reads_size_limit_nonatomic = limit; + } + stm_begin_transaction(buf, longjmp_callback); + } +} + +void stm_invalidate_jmp_buf(void *buf) +{ /* must save roots around this call */ + struct tx_descriptor *d = thread_descriptor; + if (d->setjmp_buf == buf) { + BecomeInevitable("stm_invalidate_jmp_buf with atomic"); + } +} + void stm_commit_transaction(void) { /* must save roots around this call */ struct tx_descriptor *d = thread_descriptor; From noreply at buildbot.pypy.org Mon Sep 23 17:34:42 2013 From: noreply at buildbot.pypy.org (arigo) Date: Mon, 23 Sep 2013 17:34:42 +0200 (CEST) Subject: [pypy-commit] stmgc default: Fix running test_zdemo_random, at least on some Linuxes where too many mprotect() eventually fail. Message-ID: <20130923153442.5BC761C34C9@cobra.cs.uni-duesseldorf.de> Author: Armin Rigo Branch: Changeset: r532:6184784a65a0 Date: 2013-09-23 17:34 +0200 http://bitbucket.org/pypy/stmgc/changeset/6184784a65a0/ Log: Fix running test_zdemo_random, at least on some Linuxes where too many mprotect() eventually fail. diff --git a/c4/dbgmem.c b/c4/dbgmem.c --- a/c4/dbgmem.c +++ b/c4/dbgmem.c @@ -14,6 +14,7 @@ static char *zone_start, *zone_current = NULL, *zone_end = NULL; static signed char accessible_pages[MMAP_TOTAL / PAGE_SIZE] = {0}; +int stm_use_mprotect = 1; static void _stm_dbgmem(void *p, size_t sz, int prot) { @@ -24,9 +25,11 @@ intptr_t align = ((intptr_t)p) & (PAGE_SIZE-1); p = ((char *)p) - align; sz += align; - dprintf(("dbgmem: %p, %ld, %d\n", p, (long)sz, prot)); - int err = mprotect(p, sz, prot); - assert(err == 0); + if (stm_use_mprotect) { + dprintf(("dbgmem: %p, %ld, %d\n", p, (long)sz, prot)); + int err = mprotect(p, sz, prot); + assert(err == 0); + } } void *stm_malloc(size_t sz) @@ -36,7 +39,7 @@ #ifdef _GC_MEMPROTECT pthread_mutex_lock(&malloc_mutex); if (zone_current == NULL) { - zone_start = mmap(NULL, MMAP_TOTAL, PROT_NONE, + zone_start = mmap(NULL, MMAP_TOTAL, PROT_READ | PROT_WRITE, MAP_PRIVATE | MAP_ANONYMOUS, -1, 0); if (zone_start == NULL || zone_start == MAP_FAILED) { stm_fatalerror("not enough memory: mmap() failed\n"); diff --git a/c4/demo_random.c b/c4/demo_random.c --- a/c4/demo_random.c +++ b/c4/demo_random.c @@ -782,11 +782,17 @@ printf("started new thread\n"); } +#ifdef _GC_MEMPROTECT +extern int stm_use_mprotect; +#endif int main(void) { int i, status; +#ifdef _GC_MEMPROTECT + stm_use_mprotect = 0; /* uses too much memory */ +#endif /* pick a random seed from the time in seconds. A bit pointless for now... because the interleaving of the From noreply at buildbot.pypy.org Mon Sep 23 20:04:21 2013 From: noreply at buildbot.pypy.org (rlamy) Date: Mon, 23 Sep 2013 20:04:21 +0200 (CEST) Subject: [pypy-commit] pypy less-stringly-ops: remove some uses of FSFrame.do_operation() Message-ID: <20130923180422.008751C0203@cobra.cs.uni-duesseldorf.de> Author: Ronan Lamy Branch: less-stringly-ops Changeset: r67071:b5e9fabfc2a4 Date: 2013-09-23 04:45 +0100 http://bitbucket.org/pypy/pypy/changeset/b5e9fabfc2a4/ Log: remove some uses of FSFrame.do_operation() diff --git a/rpython/flowspace/flowcontext.py b/rpython/flowspace/flowcontext.py --- a/rpython/flowspace/flowcontext.py +++ b/rpython/flowspace/flowcontext.py @@ -715,7 +715,7 @@ def PRINT_ITEM(self, oparg): w_item = self.popvalue() - w_s = self.do_operation('str', w_item) + w_s = self.space.str(w_item) self.space.appcall(rpython_print_item, w_s) def PRINT_NEWLINE(self, oparg): diff --git a/rpython/flowspace/objspace.py b/rpython/flowspace/objspace.py --- a/rpython/flowspace/objspace.py +++ b/rpython/flowspace/objspace.py @@ -160,7 +160,7 @@ if not self.frame.guessbool(self.bool(w_correct)): w_exc = self.exc_from_raise(self.w_ValueError, self.w_None) raise Raise(w_exc) - return [self.frame.do_operation('getitem', w_iterable, const(i)) + return [self.getitem(w_iterable, const(i)) for i in range(expected_length)] # ____________________________________________________________ @@ -199,7 +199,7 @@ def appcall(self, func, *args_w): """Call an app-level RPython function directly""" w_func = const(func) - return self.frame.do_operation('simple_call', w_func, *args_w) + return op.simple_call(w_func, *args_w).eval(self.frame) def call(self, w_callable, args): if isinstance(w_callable, Constant): diff --git a/rpython/flowspace/specialcase.py b/rpython/flowspace/specialcase.py --- a/rpython/flowspace/specialcase.py +++ b/rpython/flowspace/specialcase.py @@ -34,14 +34,12 @@ def sc_isinstance(space, w_instance, w_type): if w_instance.foldable() and w_type.foldable(): return const(isinstance(w_instance.value, w_type.value)) - return space.frame.do_operation('simple_call', const(isinstance), - w_instance, w_type) + return space.appcall(isinstance, w_instance, w_type) @register_flow_sc(getattr) def sc_getattr(space, w_obj, w_index, w_default=None): if w_default is not None: - return space.frame.do_operation('simple_call', const(getattr), w_obj, - w_index, w_default) + return space.appcall(getattr, w_obj, w_index, w_default) else: return space.getattr(w_obj, w_index) diff --git a/rpython/rlib/rarithmetic.py b/rpython/rlib/rarithmetic.py --- a/rpython/rlib/rarithmetic.py +++ b/rpython/rlib/rarithmetic.py @@ -521,7 +521,7 @@ # show up in the flow graphs at all) if isinstance(w_value, Constant): return Constant(r_uint(w_value.value)) - return space.frame.do_operation('simple_call', const(r_uint), w_value) + return space.appcall(r_uint, w_value) r_longlong = build_int('r_longlong', True, 64) From noreply at buildbot.pypy.org Mon Sep 23 20:04:23 2013 From: noreply at buildbot.pypy.org (rlamy) Date: Mon, 23 Sep 2013 20:04:23 +0200 (CEST) Subject: [pypy-commit] pypy less-stringly-ops: kill FSFrame.do_operation() Message-ID: <20130923180423.399AA1C0203@cobra.cs.uni-duesseldorf.de> Author: Ronan Lamy Branch: less-stringly-ops Changeset: r67072:d0ba87deddde Date: 2013-09-23 05:43 +0100 http://bitbucket.org/pypy/pypy/changeset/d0ba87deddde/ Log: kill FSFrame.do_operation() diff --git a/rpython/flowspace/flowcontext.py b/rpython/flowspace/flowcontext.py --- a/rpython/flowspace/flowcontext.py +++ b/rpython/flowspace/flowcontext.py @@ -419,11 +419,6 @@ return w_condition.value return self.recorder.guessbool(self, w_condition) - def do_operation(self, name, *args_w): - spaceop = SpaceOperation(name, args_w, Variable()) - self.record(spaceop) - return spaceop.result - def record(self, spaceop): recorder = self.recorder if getattr(recorder, 'final_state', None) is not None: @@ -704,7 +699,7 @@ def YIELD_VALUE(self, _): assert self.pycode.is_generator w_result = self.popvalue() - self.do_operation('yield', w_result) + self.space.yield_(w_result) # XXX yield expressions not supported. This will blow up if the value # isn't popped straightaway. self.pushvalue(None) @@ -916,7 +911,7 @@ # This opcode was added with pypy-1.8. Here is a simpler # version, enough for annotation. last_val = self.popvalue() - self.pushvalue(self.space.newlist([])) + self.pushvalue(self.space.newlist()) self.pushvalue(last_val) def call_function(self, oparg, w_star=None, w_starstar=None): @@ -1082,12 +1077,12 @@ def BUILD_TUPLE(self, itemcount): items = self.popvalues(itemcount) - w_tuple = self.space.newtuple(items) + w_tuple = self.space.newtuple(*items) self.pushvalue(w_tuple) def BUILD_LIST(self, itemcount): items = self.popvalues(itemcount) - w_list = self.space.newlist(items) + w_list = self.space.newlist(*items) self.pushvalue(w_list) def BUILD_MAP(self, itemcount): diff --git a/rpython/flowspace/generator.py b/rpython/flowspace/generator.py --- a/rpython/flowspace/generator.py +++ b/rpython/flowspace/generator.py @@ -128,7 +128,7 @@ assert block is not stopblock for index in range(len(block.operations)-1, -1, -1): op = block.operations[index] - if op.opname == 'yield': + if op.opname == 'yield_': [v_yielded_value] = op.args del block.operations[index] newlink = split_block(None, block, index) diff --git a/rpython/flowspace/objspace.py b/rpython/flowspace/objspace.py --- a/rpython/flowspace/objspace.py +++ b/rpython/flowspace/objspace.py @@ -60,25 +60,6 @@ def build_flow(self, func): return build_flow(func, self) - is_ = None # real version added by add_operations() - id = None # real version added by add_operations() - - def newdict(self, module="ignored"): - return self.frame.do_operation('newdict') - - def newtuple(self, args_w): - if all(isinstance(w_arg, Constant) for w_arg in args_w): - content = [w_arg.value for w_arg in args_w] - return Constant(tuple(content)) - else: - return self.frame.do_operation('newtuple', *args_w) - - def newlist(self, args_w, sizehint=None): - return self.frame.do_operation('newlist', *args_w) - - def newslice(self, w_start, w_stop, w_step): - return self.frame.do_operation('newslice', w_start, w_stop, w_step) - def newbool(self, b): if b: return self.w_True diff --git a/rpython/flowspace/operation.py b/rpython/flowspace/operation.py --- a/rpython/flowspace/operation.py +++ b/rpython/flowspace/operation.py @@ -300,6 +300,12 @@ add_operator('delete', 2, pyfunc=delete) add_operator('userdel', 1, pyfunc=userdel) add_operator('buffer', 1, pyfunc=buffer, pure=True) # see buffer.py +add_operator('yield_', 1) +add_operator('newdict', 0) +add_operator('newtuple', None, pure=True, pyfunc=lambda *args:args) +add_operator('newlist', None) +add_operator('newslice', 3) + class Pow(PureOperation): opname = 'pow' From noreply at buildbot.pypy.org Mon Sep 23 23:13:35 2013 From: noreply at buildbot.pypy.org (amauryfa) Date: Mon, 23 Sep 2013 23:13:35 +0200 (CEST) Subject: [pypy-commit] pypy default: Fix most of test_ssl, when run with the 'network' resource: Message-ID: <20130923211335.BD1EA1C01CC@cobra.cs.uni-duesseldorf.de> Author: Amaury Forgeot d'Arc Branch: Changeset: r67073:e67bff72a81a Date: 2013-09-23 23:03 +0200 http://bitbucket.org/pypy/pypy/changeset/e67bff72a81a/ Log: Fix most of test_ssl, when run with the 'network' resource: pypy -m test.regrtest -u network -v test_ssl diff --git a/lib-python/2.7/test/keycert.pem b/lib-python/2.7/test/keycert.pem --- a/lib-python/2.7/test/keycert.pem +++ b/lib-python/2.7/test/keycert.pem @@ -1,32 +1,31 @@ ------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 PRIVATE KEY----- +MIICdwIBADANBgkqhkiG9w0BAQEFAASCAmEwggJdAgEAAoGBANtb0+YrKuxevGpm +LrjaUhZSgz6zFAmuGFmKmUbdjmfv9zSmmdsQIksK++jK0Be9LeZy20j6ahOfuVa0 +ufEmPoP7Fy4hXegKZR9cCWcIe/A6H2xWF1IIJLRTLaU8ol/I7T+um5HD5AwAwNPP +USNU0Eegmvp+xxWu3NX2m1Veot85AgMBAAECgYA3ZdZ673X0oexFlq7AAmrutkHt +CL7LvwrpOiaBjhyTxTeSNWzvtQBkIU8DOI0bIazA4UreAFffwtvEuPmonDb3F+Iq +SMAu42XcGyVZEl+gHlTPU9XRX7nTOXVt+MlRRRxL6t9GkGfUAXI3XxJDXW3c0vBK +UL9xqD8cORXOfE06rQJBAP8mEX1ERkR64Ptsoe4281vjTlNfIbs7NMPkUnrn9N/Y +BLhjNIfQ3HFZG8BTMLfX7kCS9D593DW5tV4Z9BP/c6cCQQDcFzCcVArNh2JSywOQ +ZfTfRbJg/Z5Lt9Fkngv1meeGNPgIMLN8Sg679pAOOWmzdMO3V706rNPzSVMME7E5 +oPIfAkEA8pDddarP5tCvTTgUpmTFbakm0KoTZm2+FzHcnA4jRh+XNTjTOv98Y6Ik +eO5d1ZnKXseWvkZncQgxfdnMqqpj5wJAcNq/RVne1DbYlwWchT2Si65MYmmJ8t+F +0mcsULqjOnEMwf5e+ptq5LzwbyrHZYq5FNk7ocufPv/ZQrcSSC+cFwJBAKvOJByS +x56qyGeZLOQlWS2JS3KJo59XuLFGqcbgN9Om9xFa41Yb4N9NvplFivsvZdw3m1Q/ +SPIXQuT8RMPDVNQ= +-----END PRIVATE KEY----- -----BEGIN CERTIFICATE----- -MIICpzCCAhCgAwIBAgIJAP+qStv1cIGNMA0GCSqGSIb3DQEBBQUAMIGJMQswCQYD -VQQGEwJVUzERMA8GA1UECBMIRGVsYXdhcmUxEzARBgNVBAcTCldpbG1pbmd0b24x -IzAhBgNVBAoTGlB5dGhvbiBTb2Z0d2FyZSBGb3VuZGF0aW9uMQwwCgYDVQQLEwNT -U0wxHzAdBgNVBAMTFnNvbWVtYWNoaW5lLnB5dGhvbi5vcmcwHhcNMDcwODI3MTY1 -NDUwWhcNMTMwMjE2MTY1NDUwWjCBiTELMAkGA1UEBhMCVVMxETAPBgNVBAgTCERl -bGF3YXJlMRMwEQYDVQQHEwpXaWxtaW5ndG9uMSMwIQYDVQQKExpQeXRob24gU29m -dHdhcmUgRm91bmRhdGlvbjEMMAoGA1UECxMDU1NMMR8wHQYDVQQDExZzb21lbWFj -aGluZS5weXRob24ub3JnMIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQC8ddrh -m+LutBvjYcQlnH21PPIseJ1JVG2HMmN2CmZk2YukO+9LopdJhTvbGfEj0DQs1IE8 -M+kTUyOmuKfVrFMKwtVeCJphrAnhoz7TYOuLBSqt7lVHfhi/VwovESJlaBOp+WMn -fhcduPEYHYx/6cnVapIkZnLt30zu2um+DzA9jQIDAQABoxUwEzARBglghkgBhvhC -AQEEBAMCBkAwDQYJKoZIhvcNAQEFBQADgYEAF4Q5BVqmCOLv1n8je/Jw9K669VXb -08hyGzQhkemEBYQd6fzQ9A/1ZzHkJKb1P6yreOLSEh4KcxYPyrLRC1ll8nr5OlCx -CMhKkTnR6qBsdNV0XtdU2+N25hqW+Ma4ZeqsN/iiJVCGNOZGnvQuvCAGWF8+J/f/ -iHkC6gGdBJhogs4= +MIICVDCCAb2gAwIBAgIJANfHOBkZr8JOMA0GCSqGSIb3DQEBBQUAMF8xCzAJBgNV +BAYTAlhZMRcwFQYDVQQHEw5DYXN0bGUgQW50aHJheDEjMCEGA1UEChMaUHl0aG9u +IFNvZnR3YXJlIEZvdW5kYXRpb24xEjAQBgNVBAMTCWxvY2FsaG9zdDAeFw0xMDEw +MDgyMzAxNTZaFw0yMDEwMDUyMzAxNTZaMF8xCzAJBgNVBAYTAlhZMRcwFQYDVQQH +Ew5DYXN0bGUgQW50aHJheDEjMCEGA1UEChMaUHl0aG9uIFNvZnR3YXJlIEZvdW5k +YXRpb24xEjAQBgNVBAMTCWxvY2FsaG9zdDCBnzANBgkqhkiG9w0BAQEFAAOBjQAw +gYkCgYEA21vT5isq7F68amYuuNpSFlKDPrMUCa4YWYqZRt2OZ+/3NKaZ2xAiSwr7 +6MrQF70t5nLbSPpqE5+5VrS58SY+g/sXLiFd6AplH1wJZwh78DofbFYXUggktFMt +pTyiX8jtP66bkcPkDADA089RI1TQR6Ca+n7HFa7c1fabVV6i3zkCAwEAAaMYMBYw +FAYDVR0RBA0wC4IJbG9jYWxob3N0MA0GCSqGSIb3DQEBBQUAA4GBAHPctQBEQ4wd +BJ6+JcpIraopLn8BGhbjNWj40mmRqWB/NAWF6M5ne7KpGAu7tLeG4hb1zLaldK8G +lxy2GPSRF6LFS48dpEj2HbMv2nvv6xxalDMJ9+DicWgAKTQ6bcX2j3GUkCR0g/T1 +CRlNBAAlvhKzO7Clpf9l0YKBEfraJByX -----END CERTIFICATE----- diff --git a/lib-python/2.7/test/sha256.pem b/lib-python/2.7/test/sha256.pem --- a/lib-python/2.7/test/sha256.pem +++ b/lib-python/2.7/test/sha256.pem @@ -1,129 +1,128 @@ # Certificate chain for https://sha256.tbs-internet.com - 0 s:/C=FR/postalCode=14000/ST=Calvados/L=CAEN/street=22 rue de Bretagne/O=TBS INTERNET/OU=0002 440443810/OU=sha-256 production/CN=sha256.tbs-internet.com - i:/C=FR/ST=Calvados/L=Caen/O=TBS INTERNET/OU=Terms and Conditions: http://www.tbs-internet.com/CA/repository/OU=TBS INTERNET CA/CN=TBS X509 CA SGC + 0 s:/C=FR/postalCode=14000/ST=Calvados/L=CAEN/street=22 rue de Bretagne/O=TBS INTERNET/OU=0002 440443810/OU=Certificats TBS X509/CN=ecom.tbs-x509.com + i:/C=FR/ST=Calvados/L=Caen/O=TBS INTERNET/OU=Terms and Conditions: http://www.tbs-internet.com/CA/repository/OU=TBS INTERNET CA/CN=TBS X509 CA business -----BEGIN CERTIFICATE----- -MIIGXTCCBUWgAwIBAgIRAMmag+ygSAdxZsbyzYjhuW0wDQYJKoZIhvcNAQELBQAw -gcQxCzAJBgNVBAYTAkZSMREwDwYDVQQIEwhDYWx2YWRvczENMAsGA1UEBxMEQ2Fl +MIIGTjCCBTagAwIBAgIQOh3d9dNDPq1cSdJmEiMpqDANBgkqhkiG9w0BAQUFADCB +yTELMAkGA1UEBhMCRlIxETAPBgNVBAgTCENhbHZhZG9zMQ0wCwYDVQQHEwRDYWVu +MRUwEwYDVQQKEwxUQlMgSU5URVJORVQxSDBGBgNVBAsTP1Rlcm1zIGFuZCBDb25k +aXRpb25zOiBodHRwOi8vd3d3LnRicy1pbnRlcm5ldC5jb20vQ0EvcmVwb3NpdG9y +eTEYMBYGA1UECxMPVEJTIElOVEVSTkVUIENBMR0wGwYDVQQDExRUQlMgWDUwOSBD +QSBidXNpbmVzczAeFw0xMTAxMjUwMDAwMDBaFw0xMzAyMDUyMzU5NTlaMIHHMQsw +CQYDVQQGEwJGUjEOMAwGA1UEERMFMTQwMDAxETAPBgNVBAgTCENhbHZhZG9zMQ0w +CwYDVQQHEwRDQUVOMRswGQYDVQQJExIyMiBydWUgZGUgQnJldGFnbmUxFTATBgNV +BAoTDFRCUyBJTlRFUk5FVDEXMBUGA1UECxMOMDAwMiA0NDA0NDM4MTAxHTAbBgNV +BAsTFENlcnRpZmljYXRzIFRCUyBYNTA5MRowGAYDVQQDExFlY29tLnRicy14NTA5 +LmNvbTCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBAKRrlHUnJ++1lpcg +jtYco7cdmRe+EEfTmwPfCdfV3G1QfsTSvY6FfMpm/83pqHfT+4ANwr18wD9ZrAEN +G16mf9VdCGK12+TP7DmqeZyGIqlFFoahQnmb8EarvE43/1UeQ2CV9XmzwZvpqeli +LfXsFonawrY3H6ZnMwS64St61Z+9gdyuZ/RbsoZBbT5KUjDEG844QRU4OT1IGeEI +eY5NM5RNIh6ZNhVtqeeCxMS7afONkHQrOco73RdSTRck/Hj96Ofl3MHNHryr+AMK +DGFk1kLCZGpPdXtkxXvaDeQoiYDlil26CWc+YK6xyDPMdsWvoG14ZLyCpzMXA7/7 +4YAQRH0CAwEAAaOCAjAwggIsMB8GA1UdIwQYMBaAFBoJBMz5CY+7HqDO1KQUf0vV +I1jNMB0GA1UdDgQWBBQgOU8HsWzbmD4WZP5Wtdw7jca2WDAOBgNVHQ8BAf8EBAMC +BaAwDAYDVR0TAQH/BAIwADAdBgNVHSUEFjAUBggrBgEFBQcDAQYIKwYBBQUHAwIw +TAYDVR0gBEUwQzBBBgsrBgEEAYDlNwIBATAyMDAGCCsGAQUFBwIBFiRodHRwczov +L3d3dy50YnMtaW50ZXJuZXQuY29tL0NBL0NQUzEwdwYDVR0fBHAwbjA3oDWgM4Yx +aHR0cDovL2NybC50YnMtaW50ZXJuZXQuY29tL1RCU1g1MDlDQWJ1c2luZXNzLmNy +bDAzoDGgL4YtaHR0cDovL2NybC50YnMteDUwOS5jb20vVEJTWDUwOUNBYnVzaW5l +c3MuY3JsMIGwBggrBgEFBQcBAQSBozCBoDA9BggrBgEFBQcwAoYxaHR0cDovL2Ny +dC50YnMtaW50ZXJuZXQuY29tL1RCU1g1MDlDQWJ1c2luZXNzLmNydDA5BggrBgEF +BQcwAoYtaHR0cDovL2NydC50YnMteDUwOS5jb20vVEJTWDUwOUNBYnVzaW5lc3Mu +Y3J0MCQGCCsGAQUFBzABhhhodHRwOi8vb2NzcC50YnMteDUwOS5jb20wMwYDVR0R +BCwwKoIRZWNvbS50YnMteDUwOS5jb22CFXd3dy5lY29tLnRicy14NTA5LmNvbTAN +BgkqhkiG9w0BAQUFAAOCAQEArT4NHfbY87bGAw8lPV4DmHlmuDuVp/y7ltO3Ynse +3Rz8RxW2AzuO0Oy2F0Cu4yWKtMyEyMXyHqWtae7ElRbdTu5w5GwVBLJHClCzC8S9 +SpgMMQTx3Rgn8vjkHuU9VZQlulZyiPK7yunjc7c310S9FRZ7XxOwf8Nnx4WnB+No +WrfApzhhQl31w+RyrNxZe58hCfDDHmevRvwLjQ785ZoQXJDj2j3qAD4aI2yB8lB5 +oaE1jlCJzC7Kmz/Y9jzfmv/zAs1LQTm9ktevv4BTUFaGjv9jxnQ1xnS862ZiouLW +zZYIlYPf4F6JjXGiIQgQRglILUfq3ftJd9/ok9W9ZF8h8w== +-----END CERTIFICATE----- + 1 s:/C=FR/ST=Calvados/L=Caen/O=TBS INTERNET/OU=Terms and Conditions: http://www.tbs-internet.com/CA/repository/OU=TBS INTERNET CA/CN=TBS X509 CA business + i:/C=SE/O=AddTrust AB/OU=AddTrust External TTP Network/CN=AddTrust External CA Root +-----BEGIN CERTIFICATE----- +MIIFPzCCBCegAwIBAgIQDlBz/++iRSmLDeVRHT/hADANBgkqhkiG9w0BAQUFADBv +MQswCQYDVQQGEwJTRTEUMBIGA1UEChMLQWRkVHJ1c3QgQUIxJjAkBgNVBAsTHUFk +ZFRydXN0IEV4dGVybmFsIFRUUCBOZXR3b3JrMSIwIAYDVQQDExlBZGRUcnVzdCBF +eHRlcm5hbCBDQSBSb290MB4XDTA1MTIwMTAwMDAwMFoXDTE5MDcwOTE4MTkyMlow +gckxCzAJBgNVBAYTAkZSMREwDwYDVQQIEwhDYWx2YWRvczENMAsGA1UEBxMEQ2Fl bjEVMBMGA1UEChMMVEJTIElOVEVSTkVUMUgwRgYDVQQLEz9UZXJtcyBhbmQgQ29u ZGl0aW9uczogaHR0cDovL3d3dy50YnMtaW50ZXJuZXQuY29tL0NBL3JlcG9zaXRv -cnkxGDAWBgNVBAsTD1RCUyBJTlRFUk5FVCBDQTEYMBYGA1UEAxMPVEJTIFg1MDkg -Q0EgU0dDMB4XDTEwMDIxODAwMDAwMFoXDTEyMDIxOTIzNTk1OVowgcsxCzAJBgNV -BAYTAkZSMQ4wDAYDVQQREwUxNDAwMDERMA8GA1UECBMIQ2FsdmFkb3MxDTALBgNV -BAcTBENBRU4xGzAZBgNVBAkTEjIyIHJ1ZSBkZSBCcmV0YWduZTEVMBMGA1UEChMM -VEJTIElOVEVSTkVUMRcwFQYDVQQLEw4wMDAyIDQ0MDQ0MzgxMDEbMBkGA1UECxMS -c2hhLTI1NiBwcm9kdWN0aW9uMSAwHgYDVQQDExdzaGEyNTYudGJzLWludGVybmV0 -LmNvbTCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBAKbuM8VT7f0nntwu -N3F7v9KIBlhKNAxqCrziOXU5iqUt8HrQB3DtHbdmII+CpVUlwlmepsx6G+srEZ9a -MIGAy0nxi5aLb7watkyIdPjJTMvTUBQ/+RPWzt5JtYbbY9BlJ+yci0dctP74f4NU -ISLtlrEjUbf2gTohLrcE01TfmOF6PDEbB5PKDi38cB3NzKfizWfrOaJW6Q1C1qOJ -y4/4jkUREX1UFUIxzx7v62VfjXSGlcjGpBX1fvtABQOSLeE0a6gciDZs1REqroFf -5eXtqYphpTa14Z83ITXMfgg5Nze1VtMnzI9Qx4blYBw4dgQVEuIsYr7FDBOITDzc -VEVXZx0CAwEAAaOCAj8wggI7MB8GA1UdIwQYMBaAFAdEdoWTKLx/bXjSCuv6TEvf -2YIfMB0GA1UdDgQWBBSJKI/AYVI9RQNY0QPIqc8ej2QivTAOBgNVHQ8BAf8EBAMC -BaAwDAYDVR0TAQH/BAIwADA0BgNVHSUELTArBggrBgEFBQcDAQYIKwYBBQUHAwIG -CisGAQQBgjcKAwMGCWCGSAGG+EIEATBMBgNVHSAERTBDMEEGCysGAQQBgOU3AgQB -MDIwMAYIKwYBBQUHAgEWJGh0dHBzOi8vd3d3LnRicy1pbnRlcm5ldC5jb20vQ0Ev -Q1BTNDBtBgNVHR8EZjBkMDKgMKAuhixodHRwOi8vY3JsLnRicy1pbnRlcm5ldC5j -b20vVEJTWDUwOUNBU0dDLmNybDAuoCygKoYoaHR0cDovL2NybC50YnMteDUwOS5j -b20vVEJTWDUwOUNBU0dDLmNybDCBpgYIKwYBBQUHAQEEgZkwgZYwOAYIKwYBBQUH -MAKGLGh0dHA6Ly9jcnQudGJzLWludGVybmV0LmNvbS9UQlNYNTA5Q0FTR0MuY3J0 -MDQGCCsGAQUFBzAChihodHRwOi8vY3J0LnRicy14NTA5LmNvbS9UQlNYNTA5Q0FT -R0MuY3J0MCQGCCsGAQUFBzABhhhodHRwOi8vb2NzcC50YnMteDUwOS5jb20wPwYD -VR0RBDgwNoIXc2hhMjU2LnRicy1pbnRlcm5ldC5jb22CG3d3dy5zaGEyNTYudGJz -LWludGVybmV0LmNvbTANBgkqhkiG9w0BAQsFAAOCAQEAA5NL0D4QSqhErhlkdPmz -XtiMvdGL+ZehM4coTRIpasM/Agt36Rc0NzCvnQwKE+wkngg1Gy2qe7Q0E/ziqBtB -fZYzdVgu1zdiL4kTaf+wFKYAFGsFbyeEmXysy+CMwaNoF2vpSjCU1UD56bEnTX/W -fxVZYxtBQUpnu2wOsm8cDZuZRv9XrYgAhGj9Tt6F0aVHSDGn59uwShG1+BVF/uju -SCyPTTjL1oc7YElJUzR/x4mQJYvtQI8gDIDAGEOs7v3R/gKa5EMfbUQUI4C84UbI -Yz09Jdnws/MkC/Hm1BZEqk89u7Hvfv+oHqEb0XaUo0TDfsxE0M1sMdnLb91QNQBm -UQ== ------END CERTIFICATE----- - 1 s:/C=FR/ST=Calvados/L=Caen/O=TBS INTERNET/OU=Terms and Conditions: http://www.tbs-internet.com/CA/repository/OU=TBS INTERNET CA/CN=TBS X509 CA SGC - i:/C=SE/O=AddTrust AB/OU=AddTrust External TTP Network/CN=AddTrust External CA Root ------BEGIN CERTIFICATE----- -MIIFVjCCBD6gAwIBAgIQXpDZ0ETJMV02WTx3GTnhhTANBgkqhkiG9w0BAQUFADBv -MQswCQYDVQQGEwJTRTEUMBIGA1UEChMLQWRkVHJ1c3QgQUIxJjAkBgNVBAsTHUFk -ZFRydXN0IEV4dGVybmFsIFRUUCBOZXR3b3JrMSIwIAYDVQQDExlBZGRUcnVzdCBF -eHRlcm5hbCBDQSBSb290MB4XDTA1MTIwMTAwMDAwMFoXDTE5MDYyNDE5MDYzMFow -gcQxCzAJBgNVBAYTAkZSMREwDwYDVQQIEwhDYWx2YWRvczENMAsGA1UEBxMEQ2Fl -bjEVMBMGA1UEChMMVEJTIElOVEVSTkVUMUgwRgYDVQQLEz9UZXJtcyBhbmQgQ29u -ZGl0aW9uczogaHR0cDovL3d3dy50YnMtaW50ZXJuZXQuY29tL0NBL3JlcG9zaXRv -cnkxGDAWBgNVBAsTD1RCUyBJTlRFUk5FVCBDQTEYMBYGA1UEAxMPVEJTIFg1MDkg -Q0EgU0dDMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAsgOkO3f7wzN6 -rOjg45tR5vjBfzK7qmV9IBxb/QW9EEXxG+E7FNhZqQLtwGBKoSsHTnQqV75wWMk0 -9tinWvftBkSpj5sTi/8cbzJfUvTSVYh3Qxv6AVVjMMH/ruLjE6y+4PoaPs8WoYAQ -ts5R4Z1g8c/WnTepLst2x0/Wv7GmuoQi+gXvHU6YrBiu7XkeYhzc95QdviWSJRDk -owhb5K43qhcvjRmBfO/paGlCliDGZp8mHwrI21mwobWpVjTxZRwYO3bd4+TGcI4G -Ie5wmHwE8F7SK1tgSqbBacKjDa93j7txKkfz/Yd2n7TGqOXiHPsJpG655vrKtnXk -9vs1zoDeJQIDAQABo4IBljCCAZIwHQYDVR0OBBYEFAdEdoWTKLx/bXjSCuv6TEvf -2YIfMA4GA1UdDwEB/wQEAwIBBjASBgNVHRMBAf8ECDAGAQH/AgEAMCAGA1UdJQQZ -MBcGCisGAQQBgjcKAwMGCWCGSAGG+EIEATAYBgNVHSAEETAPMA0GCysGAQQBgOU3 -AgQBMHsGA1UdHwR0MHIwOKA2oDSGMmh0dHA6Ly9jcmwuY29tb2RvY2EuY29tL0Fk -ZFRydXN0RXh0ZXJuYWxDQVJvb3QuY3JsMDagNKAyhjBodHRwOi8vY3JsLmNvbW9k -by5uZXQvQWRkVHJ1c3RFeHRlcm5hbENBUm9vdC5jcmwwgYAGCCsGAQUFBwEBBHQw -cjA4BggrBgEFBQcwAoYsaHR0cDovL2NydC5jb21vZG9jYS5jb20vQWRkVHJ1c3RV -VE5TR0NDQS5jcnQwNgYIKwYBBQUHMAKGKmh0dHA6Ly9jcnQuY29tb2RvLm5ldC9B -ZGRUcnVzdFVUTlNHQ0NBLmNydDARBglghkgBhvhCAQEEBAMCAgQwDQYJKoZIhvcN -AQEFBQADggEBAK2zEzs+jcIrVK9oDkdDZNvhuBYTdCfpxfFs+OAujW0bIfJAy232 -euVsnJm6u/+OrqKudD2tad2BbejLLXhMZViaCmK7D9nrXHx4te5EP8rL19SUVqLY -1pTnv5dhNgEgvA7n5lIzDSYs7yRLsr7HJsYPr6SeYSuZizyX1SNz7ooJ32/F3X98 -RB0Mlc/E0OyOrkQ9/y5IrnpnaSora8CnUrV5XNOg+kyCz9edCyx4D5wXYcwZPVWz -8aDqquESrezPyjtfi4WRO4s/VD3HLZvOxzMrWAVYCDG9FxaOhF0QGuuG1F7F3GKV -v6prNyCl016kRl2j1UT+a7gLd8fA25A4C9E= +cnkxGDAWBgNVBAsTD1RCUyBJTlRFUk5FVCBDQTEdMBsGA1UEAxMUVEJTIFg1MDkg +Q0EgYnVzaW5lc3MwggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQDB1PAU +qudCcz3tmyGcf+u6EkZqonKKHrV4gZYbvVkIRojmmlhfi/jwvpHvo8bqSt/9Rj5S +jhCDW0pcbI+IPPtD1Jy+CHNSfnMqVDy6CKQ3p5maTzCMG6ZT+XjnvcND5v+FtaiB +xk1iCX6uvt0jeUtdZvYbyytsSDE6c3Y5//wRxOF8tM1JxibwO3pyER26jbbN2gQz +m/EkdGjLdJ4svPk23WDAvQ6G0/z2LcAaJB+XLfqRwfQpHQvfKa1uTi8PivC8qtip +rmNQMMPMjxSK2azX8cKjjTDJiUKaCb4VHlJDWKEsCFRpgJAoAuX8f7Yfs1M4esGo +sWb3PGspK3O22uIlAgMBAAGjggF6MIIBdjAdBgNVHQ4EFgQUGgkEzPkJj7seoM7U +pBR/S9UjWM0wDgYDVR0PAQH/BAQDAgEGMBIGA1UdEwEB/wQIMAYBAf8CAQAwGAYD +VR0gBBEwDzANBgsrBgEEAYDlNwIBATB7BgNVHR8EdDByMDigNqA0hjJodHRwOi8v +Y3JsLmNvbW9kb2NhLmNvbS9BZGRUcnVzdEV4dGVybmFsQ0FSb290LmNybDA2oDSg +MoYwaHR0cDovL2NybC5jb21vZG8ubmV0L0FkZFRydXN0RXh0ZXJuYWxDQVJvb3Qu +Y3JsMIGGBggrBgEFBQcBAQR6MHgwOwYIKwYBBQUHMAKGL2h0dHA6Ly9jcnQuY29t +b2RvY2EuY29tL0FkZFRydXN0VVROU2VydmVyQ0EuY3J0MDkGCCsGAQUFBzAChi1o +dHRwOi8vY3J0LmNvbW9kby5uZXQvQWRkVHJ1c3RVVE5TZXJ2ZXJDQS5jcnQwEQYJ +YIZIAYb4QgEBBAQDAgIEMA0GCSqGSIb3DQEBBQUAA4IBAQA7mqrMgk/MrE6QnbNA +h4nRCn2ti4bg4w2C3lB6bSvRPnYwuNw9Jb8vuKkNFzRDxNJXqVDZdfFW5CVQJuyd +nfAx83+wk+spzvFaE1KhFYfN9G9pQfXUfvDRoIcJgPEKUXL1wRiOG+IjU3VVI8pg +IgqHkr7ylln5i5zCiFAPuIJmYUSFg/gxH5xkCNcjJqqrHrHatJr6Qrrke93joupw +oU1njfAcZtYp6fbiK6u2b1pJqwkVBE8RsfLnPhRj+SFbpvjv8Od7o/ieJhFIYQNU +k2jX2u8qZnAiNw93LZW9lpYjtuvMXq8QQppENNja5b53q7UwI+lU7ZGjZ7quuESp +J6/5 -----END CERTIFICATE----- 2 s:/C=SE/O=AddTrust AB/OU=AddTrust External TTP Network/CN=AddTrust External CA Root - i:/C=US/ST=UT/L=Salt Lake City/O=The USERTRUST Network/OU=http://www.usertrust.com/CN=UTN - DATACorp SGC + i:/C=US/ST=UT/L=Salt Lake City/O=The USERTRUST Network/OU=http://www.usertrust.com/CN=UTN-USERFirst-Hardware -----BEGIN CERTIFICATE----- -MIIEZjCCA06gAwIBAgIQUSYKkxzif5zDpV954HKugjANBgkqhkiG9w0BAQUFADCB -kzELMAkGA1UEBhMCVVMxCzAJBgNVBAgTAlVUMRcwFQYDVQQHEw5TYWx0IExha2Ug +MIIETzCCAzegAwIBAgIQHM5EYpUZep1jUvnyI6m2mDANBgkqhkiG9w0BAQUFADCB +lzELMAkGA1UEBhMCVVMxCzAJBgNVBAgTAlVUMRcwFQYDVQQHEw5TYWx0IExha2Ug Q2l0eTEeMBwGA1UEChMVVGhlIFVTRVJUUlVTVCBOZXR3b3JrMSEwHwYDVQQLExho -dHRwOi8vd3d3LnVzZXJ0cnVzdC5jb20xGzAZBgNVBAMTElVUTiAtIERBVEFDb3Jw -IFNHQzAeFw0wNTA2MDcwODA5MTBaFw0xOTA2MjQxOTA2MzBaMG8xCzAJBgNVBAYT -AlNFMRQwEgYDVQQKEwtBZGRUcnVzdCBBQjEmMCQGA1UECxMdQWRkVHJ1c3QgRXh0 -ZXJuYWwgVFRQIE5ldHdvcmsxIjAgBgNVBAMTGUFkZFRydXN0IEV4dGVybmFsIENB -IFJvb3QwggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQC39xoz5vIABC05 -4E5b7R+8bA/Ntfojts7emxEzl6QpTH2Tn71KvJPtAxrjj8/lbVBa1pcplFqAsEl6 -2y6V/bjKvzc4LR4+kUGtcFbH8E8/6DKedMrIkFTpxl8PeJ2aQDwOrGGqXhSPnoeh -alDc15pOrwWzpnGUnHGzUGAKxxOdOAeGAqjpqGkmGJCrTLBPI6s6T4TY386f4Wlv -u9dC12tE5Met7m1BX3JacQg3s3llpFmglDf3AC8NwpJy2tA4ctsUqEXEXSp9t7TW -xO6szRNEt8kr3UMAJfphuWlqWCMRt6czj1Z1WfXNKddGtworZbbTQm8Vsrh7++/p -XVPVNFonAgMBAAGjgdgwgdUwHwYDVR0jBBgwFoAUUzLRs89/+uDxoF2FTpLSnkUd -tE8wHQYDVR0OBBYEFK29mHo0tCb3+sQmVO8DveAky1QaMA4GA1UdDwEB/wQEAwIB -BjAPBgNVHRMBAf8EBTADAQH/MBEGCWCGSAGG+EIBAQQEAwIBAjAgBgNVHSUEGTAX -BgorBgEEAYI3CgMDBglghkgBhvhCBAEwPQYDVR0fBDYwNDAyoDCgLoYsaHR0cDov -L2NybC51c2VydHJ1c3QuY29tL1VUTi1EQVRBQ29ycFNHQy5jcmwwDQYJKoZIhvcN -AQEFBQADggEBAMbuUxdoFLJRIh6QWA2U/b3xcOWGLcM2MY9USEbnLQg3vGwKYOEO -rVE04BKT6b64q7gmtOmWPSiPrmQH/uAB7MXjkesYoPF1ftsK5p+R26+udd8jkWjd -FwBaS/9kbHDrARrQkNnHptZt9hPk/7XJ0h4qy7ElQyZ42TCbTg0evmnv3+r+LbPM -+bDdtRTKkdSytaX7ARmjR3mfnYyVhzT4HziS2jamEfpr62vp3EV4FTkG101B5CHI -3C+H0be/SGB1pWLLJN47YaApIKa+xWycxOkKaSLvkTr6Jq/RW0GnOuL4OAdCq8Fb -+M5tug8EPzI0rNwEKNdwMBQmBsTkm5jVz3g= +dHRwOi8vd3d3LnVzZXJ0cnVzdC5jb20xHzAdBgNVBAMTFlVUTi1VU0VSRmlyc3Qt +SGFyZHdhcmUwHhcNMDUwNjA3MDgwOTEwWhcNMTkwNzA5MTgxOTIyWjBvMQswCQYD +VQQGEwJTRTEUMBIGA1UEChMLQWRkVHJ1c3QgQUIxJjAkBgNVBAsTHUFkZFRydXN0 +IEV4dGVybmFsIFRUUCBOZXR3b3JrMSIwIAYDVQQDExlBZGRUcnVzdCBFeHRlcm5h +bCBDQSBSb290MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAt/caM+by +AAQtOeBOW+0fvGwPzbX6I7bO3psRM5ekKUx9k5+9SryT7QMa44/P5W1QWtaXKZRa +gLBJetsulf24yr83OC0ePpFBrXBWx/BPP+gynnTKyJBU6cZfD3idmkA8Dqxhql4U +j56HoWpQ3NeaTq8Fs6ZxlJxxs1BgCscTnTgHhgKo6ahpJhiQq0ywTyOrOk+E2N/O +n+Fpb7vXQtdrROTHre5tQV9yWnEIN7N5ZaRZoJQ39wAvDcKSctrQOHLbFKhFxF0q +fbe01sTurM0TRLfJK91DACX6YblpalgjEbenM49WdVn1zSnXRrcKK2W200JvFbK4 +e/vv6V1T1TRaJwIDAQABo4G9MIG6MB8GA1UdIwQYMBaAFKFyXyYbKJhDlV0HN9WF +lp1L0sNFMB0GA1UdDgQWBBStvZh6NLQm9/rEJlTvA73gJMtUGjAOBgNVHQ8BAf8E +BAMCAQYwDwYDVR0TAQH/BAUwAwEB/zARBglghkgBhvhCAQEEBAMCAQIwRAYDVR0f +BD0wOzA5oDegNYYzaHR0cDovL2NybC51c2VydHJ1c3QuY29tL1VUTi1VU0VSRmly +c3QtSGFyZHdhcmUuY3JsMA0GCSqGSIb3DQEBBQUAA4IBAQByQhANOs4kClrwF8BW +onvUOGCSjRK52zYZgDXYNjDtmr5rJ6NyPFDNn+JxkLpjYetIFMTbSRe679Bt8m7a +gIAoQYFQtxMuyLnJegB2aEbQiIxh/tC21UcFF7ktdnDoTlA6w3pLuvunaI84Of3o +2YBrhzkTbCfaYk5JRlTpudW9DkUkHBsyx3nknPKnplkIGaK0jgn8E0n+SFabYaHk +I9LroYT/+JtLefh9lgBdAgVv0UPbzoGfuDsrk/Zh+UrgbLFpHoVnElhzbkh64Z0X +OGaJunQc68cCZu5HTn/aK7fBGMcVflRCXLVEQpU9PIAdGA8Ynvg684t8GMaKsRl1 +jIGZ -----END CERTIFICATE----- - 3 s:/C=US/ST=UT/L=Salt Lake City/O=The USERTRUST Network/OU=http://www.usertrust.com/CN=UTN - DATACorp SGC - i:/C=US/ST=UT/L=Salt Lake City/O=The USERTRUST Network/OU=http://www.usertrust.com/CN=UTN - DATACorp SGC + 3 s:/C=US/ST=UT/L=Salt Lake City/O=The USERTRUST Network/OU=http://www.usertrust.com/CN=UTN-USERFirst-Hardware + i:/C=US/ST=UT/L=Salt Lake City/O=The USERTRUST Network/OU=http://www.usertrust.com/CN=UTN-USERFirst-Hardware -----BEGIN CERTIFICATE----- -MIIEXjCCA0agAwIBAgIQRL4Mi1AAIbQR0ypoBqmtaTANBgkqhkiG9w0BAQUFADCB -kzELMAkGA1UEBhMCVVMxCzAJBgNVBAgTAlVUMRcwFQYDVQQHEw5TYWx0IExha2Ug +MIIEdDCCA1ygAwIBAgIQRL4Mi1AAJLQR0zYq/mUK/TANBgkqhkiG9w0BAQUFADCB +lzELMAkGA1UEBhMCVVMxCzAJBgNVBAgTAlVUMRcwFQYDVQQHEw5TYWx0IExha2Ug Q2l0eTEeMBwGA1UEChMVVGhlIFVTRVJUUlVTVCBOZXR3b3JrMSEwHwYDVQQLExho -dHRwOi8vd3d3LnVzZXJ0cnVzdC5jb20xGzAZBgNVBAMTElVUTiAtIERBVEFDb3Jw -IFNHQzAeFw05OTA2MjQxODU3MjFaFw0xOTA2MjQxOTA2MzBaMIGTMQswCQYDVQQG -EwJVUzELMAkGA1UECBMCVVQxFzAVBgNVBAcTDlNhbHQgTGFrZSBDaXR5MR4wHAYD -VQQKExVUaGUgVVNFUlRSVVNUIE5ldHdvcmsxITAfBgNVBAsTGGh0dHA6Ly93d3cu -dXNlcnRydXN0LmNvbTEbMBkGA1UEAxMSVVROIC0gREFUQUNvcnAgU0dDMIIBIjAN -BgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEA3+5YEKIrblXEjr8uRgnn4AgPLit6 -E5Qbvfa2gI5lBZMAHryv4g+OGQ0SR+ysraP6LnD43m77VkIVni5c7yPeIbkFdicZ -D0/Ww5y0vpQZY/KmEQrrU0icvvIpOxboGqBMpsn0GFlowHDyUwDAXlCCpVZvNvlK -4ESGoE1O1kduSUrLZ9emxAW5jh70/P/N5zbgnAVssjMiFdC04MwXwLLA9P4yPykq -lXvY8qdOD1R8oQ2AswkDwf9c3V6aPryuvEeKaq5xyh+xKrhfQgUL7EYw0XILyulW -bfXv33i+Ybqypa4ETLyorGkVl73v67SMvzX41MPRKA5cOp9wGDMgd8SirwIDAQAB -o4GrMIGoMAsGA1UdDwQEAwIBxjAPBgNVHRMBAf8EBTADAQH/MB0GA1UdDgQWBBRT -MtGzz3/64PGgXYVOktKeRR20TzA9BgNVHR8ENjA0MDKgMKAuhixodHRwOi8vY3Js -LnVzZXJ0cnVzdC5jb20vVVROLURBVEFDb3JwU0dDLmNybDAqBgNVHSUEIzAhBggr -BgEFBQcDAQYKKwYBBAGCNwoDAwYJYIZIAYb4QgQBMA0GCSqGSIb3DQEBBQUAA4IB -AQAnNZcAiosovcYzMB4p/OL31ZjUQLtgyr+rFywJNn9Q+kHcrpY6CiM+iVnJowft -Gzet/Hy+UUla3joKVAgWRcKZsYfNjGjgaQPpxE6YsjuMFrMOoAyYUJuTqXAJyCyj -j98C5OBxOvG0I3KgqgHf35g+FFCgMSa9KOlaMCZ1+XtgHI3zzVAmbQQnmt/VDUVH -KWss5nbZqSl9Mt3JNjy9rjXxEZ4du5A/EkdOjtd+D2JzHVImOBwYSf0wdJrE5SIv -2MCN7ZF6TACPcn9d2t0bi0Vr591pl6jFVkwPDPafepE39peC4N1xaf92P2BNPM/3 -mfnGV/TJVTl4uix5yaaIK/QI +dHRwOi8vd3d3LnVzZXJ0cnVzdC5jb20xHzAdBgNVBAMTFlVUTi1VU0VSRmlyc3Qt +SGFyZHdhcmUwHhcNOTkwNzA5MTgxMDQyWhcNMTkwNzA5MTgxOTIyWjCBlzELMAkG +A1UEBhMCVVMxCzAJBgNVBAgTAlVUMRcwFQYDVQQHEw5TYWx0IExha2UgQ2l0eTEe +MBwGA1UEChMVVGhlIFVTRVJUUlVTVCBOZXR3b3JrMSEwHwYDVQQLExhodHRwOi8v +d3d3LnVzZXJ0cnVzdC5jb20xHzAdBgNVBAMTFlVUTi1VU0VSRmlyc3QtSGFyZHdh +cmUwggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQCx98M4P7Sof885glFn +0G2f0v9Y8+efK+wNiVSZuTiZFvfgIXlIwrthdBKWHTxqctU8EGc6Oe0rE81m65UJ +M6Rsl7HoxuzBdXmcRl6Nq9Bq/bkqVRcQVLMZ8Jr28bFdtqdt++BxF2uiiPsA3/4a +MXcMmgF6sTLjKwEHOG7DpV4jvEWbe1DByTCP2+UretNb+zNAHqDVmBe8i4fDidNd +oI6yqqr2jmmIBsX6iSHzCJ1pLgkzmykNRg+MzEk0sGlRvfkGzWitZky8PqxhvQqI +DsjfPe58BEydCl5rkdbux+0ojatNh4lz0G6k0B4WixThdkQDf2Os5M1JnMWS9Ksy +oUhbAgMBAAGjgbkwgbYwCwYDVR0PBAQDAgHGMA8GA1UdEwEB/wQFMAMBAf8wHQYD +VR0OBBYEFKFyXyYbKJhDlV0HN9WFlp1L0sNFMEQGA1UdHwQ9MDswOaA3oDWGM2h0 +dHA6Ly9jcmwudXNlcnRydXN0LmNvbS9VVE4tVVNFUkZpcnN0LUhhcmR3YXJlLmNy +bDAxBgNVHSUEKjAoBggrBgEFBQcDAQYIKwYBBQUHAwUGCCsGAQUFBwMGBggrBgEF +BQcDBzANBgkqhkiG9w0BAQUFAAOCAQEARxkP3nTGmZev/K0oXnWO6y1n7k57K9cM +//bey1WiCuFMVGWTYGufEpytXoMs61quwOQt9ABjHbjAbPLPSbtNk28Gpgoiskli +CE7/yMgUsogWXecB5BKV5UU0s4tpvc+0hY91UZ59Ojg6FEgSxvunOxqNDYJAB+gE +CJChicsZUN/KHAG8HQQZexB2lzvukJDKxA4fFm517zP4029bHpbj4HR3dHuKom4t +3XbWOTCC8KucUvIqx69JXn7HaOWCgchqJ/kniCrVWFCVH/A7HFe7fRQ5YiuayZSS +KqMiDP+JJn1fIytH1xUdqWqeUQ0qUZ6B+dQ7XnASfxAynB67nfhmqA== -----END CERTIFICATE----- diff --git a/lib-python/2.7/test/test_ssl.py b/lib-python/2.7/test/test_ssl.py --- a/lib-python/2.7/test/test_ssl.py +++ b/lib-python/2.7/test/test_ssl.py @@ -111,13 +111,12 @@ if test_support.verbose: sys.stdout.write("\n" + pprint.pformat(p) + "\n") self.assertEqual(p['subject'], - ((('countryName', u'US'),), - (('stateOrProvinceName', u'Delaware'),), - (('localityName', u'Wilmington'),), - (('organizationName', u'Python Software Foundation'),), - (('organizationalUnitName', u'SSL'),), - (('commonName', u'somemachine.python.org'),)), + ((('countryName', 'XY'),), + (('localityName', 'Castle Anthrax'),), + (('organizationName', 'Python Software Foundation'),), + (('commonName', 'localhost'),)) ) + self.assertEqual(p['subjectAltName'], (('DNS', 'localhost'),)) # Issue #13034: the subjectAltName in some certificates # (notably projects.developer.nokia.com:443) wasn't parsed p = ssl._ssl._test_decode_cert(NOKIACERT) 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 @@ -399,7 +399,7 @@ proto = libssl_SSL_CIPHER_get_version(current) if proto: - w_proto = space.wrap(rffi.charp2str(name)) + w_proto = space.wrap(rffi.charp2str(proto)) else: w_proto = space.w_None @@ -476,15 +476,15 @@ w_serial = space.wrap(rffi.charpsize2str(buf, length)) space.setitem(w_retval, space.wrap("serialNumber"), w_serial) - libssl_BIO_reset(biobuf) - notBefore = libssl_X509_get_notBefore(certificate) - libssl_ASN1_TIME_print(biobuf, notBefore) - with lltype.scoped_alloc(rffi.CCHARP.TO, 100) as buf: - length = libssl_BIO_gets(biobuf, buf, 99) - if length < 0: - raise _ssl_seterror(space, None, length) - w_date = space.wrap(rffi.charpsize2str(buf, length)) - space.setitem(w_retval, space.wrap("notBefore"), w_date) + libssl_BIO_reset(biobuf) + notBefore = libssl_X509_get_notBefore(certificate) + libssl_ASN1_TIME_print(biobuf, notBefore) + with lltype.scoped_alloc(rffi.CCHARP.TO, 100) as buf: + length = libssl_BIO_gets(biobuf, buf, 99) + if length < 0: + raise _ssl_seterror(space, None, length) + w_date = space.wrap(rffi.charpsize2str(buf, length)) + space.setitem(w_retval, space.wrap("notBefore"), w_date) libssl_BIO_reset(biobuf) notAfter = libssl_X509_get_notAfter(certificate) @@ -733,7 +733,6 @@ # Set both the read and write BIO's to non-blocking mode libssl_BIO_set_nbio(libssl_SSL_get_rbio(ss.ssl), 1) libssl_BIO_set_nbio(libssl_SSL_get_wbio(ss.ssl), 1) - libssl_SSL_set_connect_state(ss.ssl) if side == PY_SSL_CLIENT: libssl_SSL_set_connect_state(ss.ssl) From noreply at buildbot.pypy.org Tue Sep 24 01:44:17 2013 From: noreply at buildbot.pypy.org (pjenvey) Date: Tue, 24 Sep 2013 01:44:17 +0200 (CEST) Subject: [pypy-commit] pypy remove-intlong-smm: fix translation Message-ID: <20130923234417.BC89C1C0203@cobra.cs.uni-duesseldorf.de> Author: Philip Jenvey Branch: remove-intlong-smm Changeset: r67074:9a188688a67a Date: 2013-09-23 14:36 -0700 http://bitbucket.org/pypy/pypy/changeset/9a188688a67a/ 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 @@ -204,7 +204,7 @@ y = space.int_w(w_exponent) try: return space.wrap(_pow_impl(space, x, y, z)) - except NotImplementedError: + except ValueError: return self._delegate2longpow(space, w_exponent, w_modulus) def _delegate2longpow(self, space, w_exponent, w_modulus): @@ -414,7 +414,7 @@ "specified") raise operationerrfmt(space.w_TypeError, msg) ## bounce it, since it always returns float - raise NotImplementedError + raise ValueError temp = iv ix = 1 try: @@ -432,7 +432,7 @@ if iz: ix = ix % iz except OverflowError: - raise NotImplementedError + raise ValueError return ix # ____________________________________________________________ From noreply at buildbot.pypy.org Tue Sep 24 01:47:24 2013 From: noreply at buildbot.pypy.org (pjenvey) Date: Tue, 24 Sep 2013 01:47:24 +0200 (CEST) Subject: [pypy-commit] pypy remove-intlong-smm: fix import, this was moved Message-ID: <20130923234724.B40531C0203@cobra.cs.uni-duesseldorf.de> Author: Philip Jenvey Branch: remove-intlong-smm Changeset: r67075:6de318712c39 Date: 2013-09-23 16:46 -0700 http://bitbucket.org/pypy/pypy/changeset/6de318712c39/ Log: fix import, this was moved diff --git a/pypy/module/pypyjit/test/test_policy.py b/pypy/module/pypyjit/test/test_policy.py --- a/pypy/module/pypyjit/test/test_policy.py +++ b/pypy/module/pypyjit/test/test_policy.py @@ -3,8 +3,8 @@ pypypolicy = policy.PyPyJitPolicy() def test_id_any(): - from pypy.objspace.std.intobject import add__Int_Int - assert pypypolicy.look_inside_function(add__Int_Int) + from pypy.objspace.std.intobject import W_IntObject + assert pypypolicy.look_inside_function(W_IntObject.descr_add) def test_bigint(): from rpython.rlib.rbigint import rbigint From noreply at buildbot.pypy.org Tue Sep 24 05:08:54 2013 From: noreply at buildbot.pypy.org (rlamy) Date: Tue, 24 Sep 2013 05:08:54 +0200 (CEST) Subject: [pypy-commit] pypy less-stringly-ops: fix Message-ID: <20130924030854.D0FBE1C01CC@cobra.cs.uni-duesseldorf.de> Author: Ronan Lamy Branch: less-stringly-ops Changeset: r67076:d377f21005e1 Date: 2013-09-24 02:57 +0100 http://bitbucket.org/pypy/pypy/changeset/d377f21005e1/ Log: fix diff --git a/rpython/flowspace/operation.py b/rpython/flowspace/operation.py --- a/rpython/flowspace/operation.py +++ b/rpython/flowspace/operation.py @@ -31,6 +31,8 @@ # built-ins that can always raise exceptions builtins_exceptions = { + int: [ValueError], + float: [ValueError], chr: [ValueError], unichr: [ValueError], unicode: [UnicodeDecodeError], From noreply at buildbot.pypy.org Tue Sep 24 05:08:56 2013 From: noreply at buildbot.pypy.org (rlamy) Date: Tue, 24 Sep 2013 05:08:56 +0200 (CEST) Subject: [pypy-commit] pypy less-stringly-ops: Simplify FlowObjSpace.import_from() Message-ID: <20130924030856.14A3F1C01CC@cobra.cs.uni-duesseldorf.de> Author: Ronan Lamy Branch: less-stringly-ops Changeset: r67077:472c03f496f5 Date: 2013-09-24 04:08 +0100 http://bitbucket.org/pypy/pypy/changeset/472c03f496f5/ Log: Simplify FlowObjSpace.import_from() diff --git a/rpython/flowspace/objspace.py b/rpython/flowspace/objspace.py --- a/rpython/flowspace/objspace.py +++ b/rpython/flowspace/objspace.py @@ -158,14 +158,9 @@ def import_from(self, w_module, w_name): assert isinstance(w_module, Constant) assert isinstance(w_name, Constant) - # handle sys - if w_module in NOT_REALLY_CONST: - const_w = NOT_REALLY_CONST[w_module] - if w_name not in const_w: - return self.frame.do_op(op.getattr(w_module, w_name)) try: - return const(getattr(w_module.value, w_name.value)) - except AttributeError: + return self.getattr(w_module, w_name) + except FlowingError: exc = ImportError("cannot import name '%s'" % w_name.value) raise Raise(const(exc)) From noreply at buildbot.pypy.org Tue Sep 24 09:49:46 2013 From: noreply at buildbot.pypy.org (fijal) Date: Tue, 24 Sep 2013 09:49:46 +0200 (CEST) Subject: [pypy-commit] pypy default: Merge a rudimentary and optional file support in RPython Message-ID: <20130924074946.428451C01CC@cobra.cs.uni-duesseldorf.de> Author: Maciej Fijalkowski Branch: Changeset: r67078:a0bf8a530d84 Date: 2013-09-24 09:49 +0200 http://bitbucket.org/pypy/pypy/changeset/a0bf8a530d84/ Log: Merge a rudimentary and optional file support in RPython diff --git a/rpython/rlib/rfile.py b/rpython/rlib/rfile.py new file mode 100644 --- /dev/null +++ b/rpython/rlib/rfile.py @@ -0,0 +1,55 @@ + +""" This file makes open() and friends RPython +""" + +import os +from rpython.annotator.model import SomeObject, SomeString, SomeInteger +from rpython.rtyper.extregistry import ExtRegistryEntry +from rpython.rtyper.extfunc import register_external + +class SomeFile(SomeObject): + def method_write(self, s_arg): + assert isinstance(s_arg, SomeString) + + def method_read(self, s_arg=None): + if s_arg is not None: + assert isinstance(s_arg, SomeInteger) + return SomeString(can_be_None=False) + + def method_close(self): + pass + + def method_seek(self, s_arg, s_whence=None): + assert isinstance(s_arg, SomeInteger) + if s_whence is not None: + assert isinstance(s_whence, SomeInteger) + + def rtyper_makekey(self): + return self.__class__, + + def rtyper_makerepr(self, rtyper): + from rpython.rtyper.lltypesystem.rfile import FileRepr + + return FileRepr(rtyper) + +class FileEntry(ExtRegistryEntry): + _about_ = open + + def compute_result_annotation(self, s_name, s_mode=None): + assert isinstance(s_name, SomeString) + if s_mode is not None: + assert isinstance(s_mode, SomeString) + return SomeFile() + + def specialize_call(self, hop): + return hop.r_result.rtype_constructor(hop) + +class OSTempfileEntry(ExtRegistryEntry): + _about_ = os.tmpfile + + def compute_result_annotation(self): + return SomeFile() + + def specialize_call(self, hop): + return hop.r_result.rtype_tempfile(hop) + diff --git a/rpython/rlib/test/test_rfile.py b/rpython/rlib/test/test_rfile.py new file mode 100644 --- /dev/null +++ b/rpython/rlib/test/test_rfile.py @@ -0,0 +1,80 @@ + +import os +from rpython.rtyper.test.tool import BaseRtypingTest +from rpython.tool.udir import udir +from rpython.rlib import rfile + +class TestFile(BaseRtypingTest): + def setup_class(cls): + cls.tmpdir = udir.join('test_rfile') + cls.tmpdir.ensure(dir=True) + + def test_open(self): + fname = str(self.tmpdir.join('file_1')) + + def f(): + f = open(fname, "w") + f.write("dupa") + f.close() + + self.interpret(f, []) + assert open(fname, "r").read() == "dupa" + + def test_read_write(self): + fname = str(self.tmpdir.join('file_2')) + + def f(): + f = open(fname, "w") + f.write("dupa") + f.close() + f2 = open(fname) + dupa = f2.read() + assert dupa == "dupa" + f2.close() + + self.interpret(f, []) + + def test_read_sequentially(self): + fname = self.tmpdir.join('file_3') + fname.write("dupa") + fname = str(fname) + + def f(): + f = open(fname) + a = f.read(1) + b = f.read(1) + c = f.read(1) + d = f.read(1) + e = f.read() + f.close() + assert a == "d" + assert b == "u" + assert c == "p" + assert d == "a" + assert e == "" + + self.interpret(f, []) + + def test_seek(self): + fname = str(self.tmpdir.join('file_4')) + + def f(): + f = open(fname, "w+") + f.write("xxx") + f.seek(0) + assert f.read() == "xxx" + f.close() + + f() + self.interpret(f, []) + + def test_tempfile(self): + def f(): + f = os.tmpfile() + f.write("xxx") + f.seek(0) + assert f.read() == "xxx" + f.close() + + f() + self.interpret(f, []) diff --git a/rpython/rtyper/lltypesystem/rfile.py b/rpython/rtyper/lltypesystem/rfile.py new file mode 100644 --- /dev/null +++ b/rpython/rtyper/lltypesystem/rfile.py @@ -0,0 +1,195 @@ + +import os +from rpython.rlib import rposix +from rpython.rlib.rarithmetic import r_uint +from rpython.annotator import model as annmodel +from rpython.rtyper.rtyper import Repr +from rpython.rlib.rstring import StringBuilder +from rpython.rtyper.lltypesystem import lltype, rffi, llmemory +from rpython.rtyper.lltypesystem.rstr import string_repr, STR +from rpython.translator.tool.cbuild import ExternalCompilationInfo +from rpython.rtyper.annlowlevel import hlstr +from rpython.rtyper.lltypesystem.lloperation import llop + +FILE = lltype.Struct('FILE') # opaque type maybe +FILE_WRAPPER = lltype.GcStruct("FileWrapper", ('file', lltype.Ptr(FILE))) + +eci = ExternalCompilationInfo(includes=['stdio.h']) + +def llexternal(*args): + return rffi.llexternal(*args, compilation_info=eci) + +c_open = llexternal('fopen', [rffi.CCHARP, rffi.CCHARP], lltype.Ptr(FILE)) +c_close = llexternal('fclose', [lltype.Ptr(FILE)], rffi.INT) +c_write = llexternal('fwrite', [rffi.CCHARP, rffi.SIZE_T, rffi.SIZE_T, + lltype.Ptr(FILE)], rffi.SIZE_T) +c_read = llexternal('fread', [rffi.CCHARP, rffi.SIZE_T, rffi.SIZE_T, + lltype.Ptr(FILE)], rffi.SIZE_T) +c_feof = llexternal('feof', [lltype.Ptr(FILE)], rffi.INT) +c_ferror = llexternal('ferror', [lltype.Ptr(FILE)], rffi.INT) +c_clearerror = llexternal('clearerr', [lltype.Ptr(FILE)], lltype.Void) +c_fseek = llexternal('fseek', [lltype.Ptr(FILE), rffi.LONG, rffi.INT], + rffi.INT) +c_tmpfile = llexternal('tmpfile', [], lltype.Ptr(FILE)) + +def ll_open(name, mode): + file_wrapper = lltype.malloc(FILE_WRAPPER) + ll_name = rffi.str2charp(name) + ll_mode = rffi.str2charp(mode) + try: + ll_f = c_open(ll_name, ll_mode) + if not ll_f: + errno = rposix.get_errno() + raise OSError(errno, os.strerror(errno)) + file_wrapper.file = ll_f + finally: + lltype.free(ll_name, flavor='raw') + lltype.free(ll_mode, flavor='raw') + return file_wrapper + +def ll_tmpfile(): + file_wrapper = lltype.malloc(FILE_WRAPPER) + res = c_tmpfile() + if not res: + errno = rposix.get_errno() + raise OSError(errno, os.strerror(errno)) + file_wrapper.file = res + return file_wrapper + +def ll_write(file_wrapper, value): + ll_file = file_wrapper.file + if not ll_file: + raise ValueError("I/O operation on closed file") + value = hlstr(value) + assert value is not None + ll_value = rffi.get_nonmovingbuffer(value) + try: + # note that since we got a nonmoving buffer, it is either raw + # or already cannot move, so the arithmetics below are fine + total_bytes = 0 + ll_current = ll_value + while total_bytes < len(value): + bytes = c_write(ll_current, 1, len(value) - r_uint(total_bytes), + ll_file) + if bytes == 0: + errno = rposix.get_errno() + raise OSError(errno, os.strerror(errno)) + total_bytes += bytes + ll_current = rffi.cast(rffi.CCHARP, + rffi.cast(lltype.Unsigned, ll_value) + + total_bytes) + finally: + rffi.free_nonmovingbuffer(value, ll_value) + +BASE_BUF_SIZE = 4096 + +def ll_read(file_wrapper, size): + ll_file = file_wrapper.file + if not ll_file: + raise ValueError("I/O operation on closed file") + if size < 0: + # read the entire contents + buf = lltype.malloc(rffi.CCHARP.TO, BASE_BUF_SIZE, flavor='raw') + try: + s = StringBuilder() + while True: + returned_size = c_read(buf, 1, BASE_BUF_SIZE, ll_file) + if returned_size == 0: + if c_feof(ll_file): + # ok, finished + return s.build() + errno = c_ferror(ll_file) + c_clearerror(ll_file) + raise OSError(errno, os.strerror(errno)) + s.append_charpsize(buf, returned_size) + finally: + lltype.free(buf, flavor='raw') + else: + raw_buf, gc_buf = rffi.alloc_buffer(size) + try: + returned_size = c_read(raw_buf, 1, size, ll_file) + if returned_size == 0: + if not c_feof(ll_file): + errno = c_ferror(ll_file) + raise OSError(errno, os.strerror(errno)) + s = rffi.str_from_buffer(raw_buf, gc_buf, size, + rffi.cast(lltype.Signed, returned_size)) + finally: + rffi.keep_buffer_alive_until_here(raw_buf, gc_buf) + return s +def ll_seek(file_wrapper, pos, whence): + ll_file = file_wrapper.file + if not ll_file: + raise ValueError("I/O operation on closed file") + res = c_fseek(ll_file, pos, whence) + if res == -1: + errno = rposix.get_errno() + raise OSError(errno, os.strerror(errno)) + +def ll_close(file_wrapper): + if file_wrapper.file: + # double close is allowed + res = c_close(file_wrapper.file) + file_wrapper.file = lltype.nullptr(FILE) + if res == -1: + errno = rposix.get_errno() + raise OSError(errno, os.strerror(errno)) + +class FileRepr(Repr): + lowleveltype = lltype.Ptr(FILE_WRAPPER) + + def __init__(self, typer): + Repr.__init__(self) + + def rtype_constructor(self, hop): + repr = hop.rtyper.getrepr(annmodel.SomeString()) + arg_0 = hop.inputarg(repr, 0) + if len(hop.args_v) == 1: + arg_1 = hop.inputconst(string_repr, "r") + else: + arg_1 = hop.inputarg(repr, 1) + hop.exception_is_here() + open = hop.rtyper.getannmixlevel().delayedfunction( + ll_open, [annmodel.SomeString()] * 2, + annmodel.SomePtr(self.lowleveltype)) + v_open = hop.inputconst(lltype.typeOf(open), open) + return hop.genop('direct_call', [v_open, arg_0, arg_1], + resulttype=self) + + def rtype_tempfile(self, hop): + tmpfile = hop.rtyper.getannmixlevel().delayedfunction( + ll_tmpfile, [], annmodel.SomePtr(self.lowleveltype)) + v_tmpfile = hop.inputconst(lltype.typeOf(tmpfile), tmpfile) + hop.exception_is_here() + return hop.genop('direct_call', [v_tmpfile], resulttype=self) + + + def rtype_method_write(self, hop): + args_v = hop.inputargs(self, string_repr) + hop.exception_is_here() + return hop.gendirectcall(ll_write, *args_v) + + def rtype_method_close(self, hop): + r_self = hop.inputarg(self, 0) + hop.exception_is_here() + return hop.gendirectcall(ll_close, r_self) + + def rtype_method_read(self, hop): + r_self = hop.inputarg(self, 0) + if len(hop.args_v) != 2: + arg_1 = hop.inputconst(lltype.Signed, -1) + else: + arg_1 = hop.inputarg(lltype.Signed, 1) + hop.exception_is_here() + return hop.gendirectcall(ll_read, r_self, arg_1) + + def rtype_method_seek(self, hop): + r_self = hop.inputarg(self, 0) + arg_1 = hop.inputarg(lltype.Signed, 1) + if len(hop.args_v) != 3: + arg_2 = hop.inputconst(lltype.Signed, os.SEEK_SET) + else: + arg_2 = hop.inputarg(lltype.Signed, 2) + hop.exception_is_here() + return hop.gendirectcall(ll_seek, r_self, arg_1, arg_2) + From noreply at buildbot.pypy.org Tue Sep 24 09:51:43 2013 From: noreply at buildbot.pypy.org (fijal) Date: Tue, 24 Sep 2013 09:51:43 +0200 (CEST) Subject: [pypy-commit] pypy default: document branch Message-ID: <20130924075143.82CFC1C01CC@cobra.cs.uni-duesseldorf.de> Author: Maciej Fijalkowski Branch: Changeset: r67079:e70f4e42689b Date: 2013-09-24 09:50 +0200 http://bitbucket.org/pypy/pypy/changeset/e70f4e42689b/ 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 @@ -101,3 +101,5 @@ Use subclasses of SpaceOperation instead of SpaceOperator objects. Random cleanups in flowspace. +.. branch: file-support-in-rpython +make open() and friends rpython From noreply at buildbot.pypy.org Tue Sep 24 09:51:45 2013 From: noreply at buildbot.pypy.org (fijal) Date: Tue, 24 Sep 2013 09:51:45 +0200 (CEST) Subject: [pypy-commit] pypy file-support-in-rpython: close merged branch Message-ID: <20130924075145.098541C01CC@cobra.cs.uni-duesseldorf.de> Author: Maciej Fijalkowski Branch: file-support-in-rpython Changeset: r67080:1d8a02bb7a70 Date: 2013-09-24 09:51 +0200 http://bitbucket.org/pypy/pypy/changeset/1d8a02bb7a70/ Log: close merged branch From noreply at buildbot.pypy.org Tue Sep 24 10:00:35 2013 From: noreply at buildbot.pypy.org (fijal) Date: Tue, 24 Sep 2013 10:00:35 +0200 (CEST) Subject: [pypy-commit] jitviewer default: add LICENSE Message-ID: <20130924080035.B0D711C01CC@cobra.cs.uni-duesseldorf.de> Author: Maciej Fijalkowski Branch: Changeset: r251:50b03fb15dac Date: 2013-09-24 10:00 +0200 http://bitbucket.org/pypy/jitviewer/changeset/50b03fb15dac/ Log: add LICENSE diff --git a/LICENSE b/LICENSE new file mode 100644 --- /dev/null +++ b/LICENSE @@ -0,0 +1,20 @@ +The MIT License + +Permission is hereby granted, free of charge, to any person +obtaining a copy of this software and associated documentation +files (the "Software"), to deal in the Software without +restriction, including without limitation the rights to use, +copy, modify, merge, publish, distribute, sublicense, and/or +sell copies of the Software, and to permit persons to whom the +Software is furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included +in all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS +OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL +THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING +FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER +DEALINGS IN THE SOFTWARE. From noreply at buildbot.pypy.org Tue Sep 24 10:00:36 2013 From: noreply at buildbot.pypy.org (fijal) Date: Tue, 24 Sep 2013 10:00:36 +0200 (CEST) Subject: [pypy-commit] jitviewer default: merge Message-ID: <20130924080036.EF59F1C01CC@cobra.cs.uni-duesseldorf.de> Author: Maciej Fijalkowski Branch: Changeset: r252:15e03325a227 Date: 2013-09-24 10:00 +0200 http://bitbucket.org/pypy/jitviewer/changeset/15e03325a227/ Log: merge diff --git a/README b/README --- a/README +++ b/README @@ -23,10 +23,6 @@ source code is (roughly) the same version as the binary pypy that produced the log file. -Finally, run it: +For usage information, invoke jitviewer.py with --help. - jitviewer.py log.pypylog - -where log.pypylog is a logfile generated by -PYPYLOG=jit-log-opt,jit-backend:log.pypylog pypy . -An example log file comes with a checkout. +An example log file is shipped with the jitviewer source code. diff --git a/_jitviewer/app.py b/_jitviewer/app.py --- a/_jitviewer/app.py +++ b/_jitviewer/app.py @@ -1,29 +1,32 @@ #!/usr/bin/env pypy -""" A web-based browser of your log files. Run by +from misc import failout - jitviewer.py [port] [--qt] +DESCR = """Jit Viewer: A web-based browser for PyPy log files""" -By default the script will run a web server, point your browser to -http://localhost:5000 +EPILOG = """ +Typical usage with no existing log file: -If you pass --qt, this script will also start a lightweight PyQT/QWebKit based -browser pointing at the jitviewer. This assumes that CPython is installed in -/usr/bin/python, and that PyQT with WebKit support is installed. + jitviewer.py --collect ... -Demo logfile available in this directory as 'log'. +Typical usage with existing log file: -To produce the logfile for your program, run: + jitviewer.py --log - PYPYLOG=jit-log-opt,jit-backend:mylogfile.pypylog pypy myapp.py +where you collected a logfile by setting PYPYLOG, e.g.: + + PYPYLOG=jit-log-opt,jit-backend: pypy arg1 ... argn + +When using an existing logfile, the source code of the logged script must be +in the same location as the logfile. + +Once invoked, jitviewer will run a web server. By default the the server +listens on http://localhost:5000 + """ import sys import os.path - -try: - import _jitviewer -except ImportError: - sys.path.insert(0, os.path.abspath(os.path.join(__file__, '..', '..'))) +import argparse try: import pypy @@ -33,12 +36,12 @@ try: import pypy except ImportError: - raise ImportError('Could not import pypy module, make sure to ' + failout('Could not import pypy module, make sure to ' 'add the pypy module to PYTHONPATH') import jinja2 if jinja2.__version__ < '2.6': - raise ImportError("Required jinja version is 2.6 (the git tip), older versions might segfault PyPy") + failout("Required jinja version is 2.6 (the git tip), older versions might segfault PyPy") import flask import inspect @@ -199,26 +202,58 @@ orig___init__(self2, *args, **kwds) BaseServer.__init__ = __init__ +def collect_log(args): + """ Collect a log file using pypy """ + import tempfile, subprocess + + print("Collecting log with: %s" % ' '.join(args)) + + # create a temp file, possibly racey, but very unlikey + (fd, path) = tempfile.mkstemp(prefix="jitviewer-") + os.close(fd) # just the filename we want + + # possibly make this configurable if someone asks... + os.environ["PYPYLOG"] = "jit-log-opt,jit-backend:%s" % (path, ) + print("Collecting log in '%s'..." % path) + p = subprocess.Popen([sys.executable] + args, env=os.environ).communicate() + + # We don't check the return status. The user may want to see traces + # for a failing program! + return os.path.abspath(path) + def main(argv, run_app=True): - if not '__pypy__' in sys.builtin_module_names: - print "Please run it using pypy-c" - sys.exit(1) - # - server_mode = True - if '--qt' in argv: - server_mode = False - argv.remove('--qt') - # - if len(argv) != 2 and len(argv) != 3: - print __doc__ - sys.exit(1) - filename = argv[1] - extra_path = os.path.dirname(filename) - if len(argv) != 3: - port = 5000 + parser = argparse.ArgumentParser( + description = DESCR, + epilog = EPILOG, + formatter_class=argparse.RawDescriptionHelpFormatter + ) + + parser.add_argument("-l", "--log", help="specify existing logfile") + parser.add_argument("-c", "--collect", nargs=argparse.REMAINDER, help="collect logfile now", metavar="ARG") + parser.add_argument("-p", "--port", help="select HTTP port", type=int) + parser.add_argument("-q", "--qt", action="store_true", help="use embedded QT browser") + + args = parser.parse_args() + + if args.port is None: + args.port = 5000 + + if args.collect is not None: + if len(args.collect) < 1: + failout("please correctly specify invokation to collect log") + filename = collect_log(args.collect) + extra_path = os.path.dirname(args.collect[0]) # add dirname of script to extra_path + elif args.log is not None: + filename = args.log + # preserving behaviour before argparse + # XXX not robust as it could be. Assumes the logfile is in the same + # dir as the source code, may not be the case. + extra_path = os.path.dirname(filename) else: - port = int(argv[2]) + failout("please specify either --log or --collect") + storage = LoopStorage(extra_path) + log, loops = import_log(filename, ParserWithHtmlRepr) parse_log_counts(extract_category(log, 'jit-backend-count'), loops) storage.loops = [loop for loop in loops @@ -231,12 +266,12 @@ app.route('/loop')(server.loop) if run_app: def run(): - app.run(use_reloader=bool(os.environ.get('JITVIEWER_USE_RELOADER', True)), host='0.0.0.0', port=port) + app.run(use_reloader=bool(os.environ.get('JITVIEWER_USE_RELOADER', False)), host='0.0.0.0', port=args.port) - if server_mode: + if not args.qt: run() else: - url = "http://localhost:%d/" % port + url = "http://localhost:%d/" % args.port run_server_and_browser(app, run, url, filename) else: return app diff --git a/_jitviewer/misc.py b/_jitviewer/misc.py new file mode 100644 --- /dev/null +++ b/_jitviewer/misc.py @@ -0,0 +1,5 @@ +import sys + +def failout(msg, exit_status = 1): + print("error: %s" % (msg, )) + sys.exit(exit_status) diff --git a/_jitviewer/static/style.css b/_jitviewer/static/style.css --- a/_jitviewer/static/style.css +++ b/_jitviewer/static/style.css @@ -232,17 +232,16 @@ font-weight: bold; } +.menu { + background: #cccccc; + text-color: red; +} + +h1 { + padding: 10px 10px 10px 10px; + background: #ffcc66; + font-size: 25px; +} + /* End of Formatting -----------------------------------------*/ - - - - - - - - - - - - diff --git a/_jitviewer/templates/index.html b/_jitviewer/templates/index.html --- a/_jitviewer/templates/index.html +++ b/_jitviewer/templates/index.html @@ -19,15 +19,18 @@
    - Menu
    + Show assembler [a]
    Show bytecode position [b]
    +

    JIT Viewer

    +
    Filter [/]:
    diff --git a/bin/jitviewer.py b/bin/jitviewer.py --- a/bin/jitviewer.py +++ b/bin/jitviewer.py @@ -1,4 +1,15 @@ #!/usr/bin/env pypy import sys +import os.path + +script_path = os.path.abspath(__file__) +pythonpath = os.path.dirname(os.path.dirname(script_path)) +sys.path.append(pythonpath) + +# Check we are running with PyPy first. +if not '__pypy__' in sys.builtin_module_names: + from _jitviewer.misc import failout + failout("jitviewer must be run with PyPy") + from _jitviewer.app import main main(sys.argv) From noreply at buildbot.pypy.org Tue Sep 24 10:30:49 2013 From: noreply at buildbot.pypy.org (fijal) Date: Tue, 24 Sep 2013 10:30:49 +0200 (CEST) Subject: [pypy-commit] pypy file-support-in-rpython: close to-be-merged branch Message-ID: <20130924083049.A244F1C02AE@cobra.cs.uni-duesseldorf.de> Author: Maciej Fijalkowski Branch: file-support-in-rpython Changeset: r67082:f104705fc807 Date: 2013-09-24 10:29 +0200 http://bitbucket.org/pypy/pypy/changeset/f104705fc807/ Log: close to-be-merged branch From noreply at buildbot.pypy.org Tue Sep 24 10:30:50 2013 From: noreply at buildbot.pypy.org (fijal) Date: Tue, 24 Sep 2013 10:30:50 +0200 (CEST) Subject: [pypy-commit] pypy default: remerge the branch Message-ID: <20130924083050.C68231C0315@cobra.cs.uni-duesseldorf.de> Author: Maciej Fijalkowski Branch: Changeset: r67083:61312092466f Date: 2013-09-24 10:30 +0200 http://bitbucket.org/pypy/pypy/changeset/61312092466f/ Log: remerge the branch 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 @@ -1678,6 +1678,17 @@ return extdef([], str, llimpl=ctermid_llimpl, export_name="ll_os.ll_os_ctermid") + @registering_if(os, 'tmpnam') + def register_os_tmpnam(self): + os_tmpnam = self.llexternal('tmpnam', [rffi.CCHARP], rffi.CCHARP) + + def tmpnam_llimpl(name): + buf = rffi.str2charp(name) + try: + return rffi.charp2str(os_tmpnam(buf)) + finally: + lltype.free(buf, flavor='raw') + # --------------------------- os.stat & variants --------------------------- @registering(os.fstat) From noreply at buildbot.pypy.org Tue Sep 24 10:30:48 2013 From: noreply at buildbot.pypy.org (fijal) Date: Tue, 24 Sep 2013 10:30:48 +0200 (CEST) Subject: [pypy-commit] pypy file-support-in-rpython: another obscure os.xyz Message-ID: <20130924083048.89AB71C01CC@cobra.cs.uni-duesseldorf.de> Author: Maciej Fijalkowski Branch: file-support-in-rpython Changeset: r67081:81e1bab40fc3 Date: 2013-09-24 10:29 +0200 http://bitbucket.org/pypy/pypy/changeset/81e1bab40fc3/ Log: another obscure os.xyz 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 @@ -1678,6 +1678,17 @@ return extdef([], str, llimpl=ctermid_llimpl, export_name="ll_os.ll_os_ctermid") + @registering_if(os, 'tmpnam') + def register_os_tmpnam(self): + os_tmpnam = self.llexternal('tmpnam', [rffi.CCHARP], rffi.CCHARP) + + def tmpnam_llimpl(name): + buf = rffi.str2charp(name) + try: + return rffi.charp2str(os_tmpnam(buf)) + finally: + lltype.free(buf, flavor='raw') + # --------------------------- os.stat & variants --------------------------- @registering(os.fstat) From noreply at buildbot.pypy.org Tue Sep 24 10:36:01 2013 From: noreply at buildbot.pypy.org (arigo) Date: Tue, 24 Sep 2013 10:36:01 +0200 (CEST) Subject: [pypy-commit] pypy incremental-gc: Add a comment Message-ID: <20130924083601.C0F0E1C01CC@cobra.cs.uni-duesseldorf.de> Author: Armin Rigo Branch: incremental-gc Changeset: r67084:49d8f5ae9b89 Date: 2013-09-24 10:35 +0200 http://bitbucket.org/pypy/pypy/changeset/49d8f5ae9b89/ Log: Add a comment diff --git a/rpython/memory/gc/incminimark.py b/rpython/memory/gc/incminimark.py --- a/rpython/memory/gc/incminimark.py +++ b/rpython/memory/gc/incminimark.py @@ -2023,6 +2023,8 @@ def _collect_ref_rec(self, root, ignored): obj = root.address[0] + # XXX minimark.py doesn't read anything from 'obj' here. + # Can this lead to seriously more cache pressure? if self.header(obj).tid & (GCFLAG_VISITED|GCFLAG_GRAY) != 0: return self.header(obj).tid |= GCFLAG_GRAY From noreply at buildbot.pypy.org Tue Sep 24 16:02:43 2013 From: noreply at buildbot.pypy.org (fijal) Date: Tue, 24 Sep 2013 16:02:43 +0200 (CEST) Subject: [pypy-commit] pypy default: ups, actually export it Message-ID: <20130924140243.881E31C12F0@cobra.cs.uni-duesseldorf.de> Author: Maciej Fijalkowski Branch: Changeset: r67085:d61a57a96a96 Date: 2013-09-24 16:01 +0200 http://bitbucket.org/pypy/pypy/changeset/d61a57a96a96/ Log: ups, actually export it 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 @@ -1689,6 +1689,9 @@ finally: lltype.free(buf, flavor='raw') + return extdef([str], None, llimpl=tmpnam_llimpl, + export_name="ll_os.ll_os_tmpnam") + # --------------------------- os.stat & variants --------------------------- @registering(os.fstat) From noreply at buildbot.pypy.org Wed Sep 25 02:19:09 2013 From: noreply at buildbot.pypy.org (pjenvey) Date: Wed, 25 Sep 2013 02:19:09 +0200 (CEST) Subject: [pypy-commit] pypy default: test bool to longs Message-ID: <20130925001909.121691C02AE@cobra.cs.uni-duesseldorf.de> Author: Philip Jenvey Branch: Changeset: r67086:4ca6d9fad665 Date: 2013-09-24 17:15 -0700 http://bitbucket.org/pypy/pypy/changeset/4ca6d9fad665/ Log: test bool to longs 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 @@ -44,6 +44,13 @@ def test_bool_int(self): assert int(True) is 1 assert int(False) is 0 + # XXX: broken + #assert True.__int__() is 1 + + def test_bool_long(self): + assert long(True) is 1L + assert long(False) is 0L + assert True.__long__() is 1L def test_bool_ops(self): assert True + True == 2 From noreply at buildbot.pypy.org Wed Sep 25 02:19:12 2013 From: noreply at buildbot.pypy.org (pjenvey) Date: Wed, 25 Sep 2013 02:19:12 +0200 (CEST) Subject: [pypy-commit] pypy remove-intlong-smm: merge default Message-ID: <20130925001912.285C01C0315@cobra.cs.uni-duesseldorf.de> Author: Philip Jenvey Branch: remove-intlong-smm Changeset: r67087:2da0d1b41394 Date: 2013-09-24 17:16 -0700 http://bitbucket.org/pypy/pypy/changeset/2da0d1b41394/ Log: merge default diff too long, truncating to 2000 out of 3475 lines diff --git a/lib-python/2.7/test/keycert.pem b/lib-python/2.7/test/keycert.pem --- a/lib-python/2.7/test/keycert.pem +++ b/lib-python/2.7/test/keycert.pem @@ -1,32 +1,31 @@ ------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 PRIVATE KEY----- +MIICdwIBADANBgkqhkiG9w0BAQEFAASCAmEwggJdAgEAAoGBANtb0+YrKuxevGpm +LrjaUhZSgz6zFAmuGFmKmUbdjmfv9zSmmdsQIksK++jK0Be9LeZy20j6ahOfuVa0 +ufEmPoP7Fy4hXegKZR9cCWcIe/A6H2xWF1IIJLRTLaU8ol/I7T+um5HD5AwAwNPP +USNU0Eegmvp+xxWu3NX2m1Veot85AgMBAAECgYA3ZdZ673X0oexFlq7AAmrutkHt +CL7LvwrpOiaBjhyTxTeSNWzvtQBkIU8DOI0bIazA4UreAFffwtvEuPmonDb3F+Iq +SMAu42XcGyVZEl+gHlTPU9XRX7nTOXVt+MlRRRxL6t9GkGfUAXI3XxJDXW3c0vBK +UL9xqD8cORXOfE06rQJBAP8mEX1ERkR64Ptsoe4281vjTlNfIbs7NMPkUnrn9N/Y +BLhjNIfQ3HFZG8BTMLfX7kCS9D593DW5tV4Z9BP/c6cCQQDcFzCcVArNh2JSywOQ +ZfTfRbJg/Z5Lt9Fkngv1meeGNPgIMLN8Sg679pAOOWmzdMO3V706rNPzSVMME7E5 +oPIfAkEA8pDddarP5tCvTTgUpmTFbakm0KoTZm2+FzHcnA4jRh+XNTjTOv98Y6Ik +eO5d1ZnKXseWvkZncQgxfdnMqqpj5wJAcNq/RVne1DbYlwWchT2Si65MYmmJ8t+F +0mcsULqjOnEMwf5e+ptq5LzwbyrHZYq5FNk7ocufPv/ZQrcSSC+cFwJBAKvOJByS +x56qyGeZLOQlWS2JS3KJo59XuLFGqcbgN9Om9xFa41Yb4N9NvplFivsvZdw3m1Q/ +SPIXQuT8RMPDVNQ= +-----END PRIVATE KEY----- -----BEGIN CERTIFICATE----- -MIICpzCCAhCgAwIBAgIJAP+qStv1cIGNMA0GCSqGSIb3DQEBBQUAMIGJMQswCQYD -VQQGEwJVUzERMA8GA1UECBMIRGVsYXdhcmUxEzARBgNVBAcTCldpbG1pbmd0b24x -IzAhBgNVBAoTGlB5dGhvbiBTb2Z0d2FyZSBGb3VuZGF0aW9uMQwwCgYDVQQLEwNT -U0wxHzAdBgNVBAMTFnNvbWVtYWNoaW5lLnB5dGhvbi5vcmcwHhcNMDcwODI3MTY1 -NDUwWhcNMTMwMjE2MTY1NDUwWjCBiTELMAkGA1UEBhMCVVMxETAPBgNVBAgTCERl -bGF3YXJlMRMwEQYDVQQHEwpXaWxtaW5ndG9uMSMwIQYDVQQKExpQeXRob24gU29m -dHdhcmUgRm91bmRhdGlvbjEMMAoGA1UECxMDU1NMMR8wHQYDVQQDExZzb21lbWFj -aGluZS5weXRob24ub3JnMIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQC8ddrh -m+LutBvjYcQlnH21PPIseJ1JVG2HMmN2CmZk2YukO+9LopdJhTvbGfEj0DQs1IE8 -M+kTUyOmuKfVrFMKwtVeCJphrAnhoz7TYOuLBSqt7lVHfhi/VwovESJlaBOp+WMn -fhcduPEYHYx/6cnVapIkZnLt30zu2um+DzA9jQIDAQABoxUwEzARBglghkgBhvhC -AQEEBAMCBkAwDQYJKoZIhvcNAQEFBQADgYEAF4Q5BVqmCOLv1n8je/Jw9K669VXb -08hyGzQhkemEBYQd6fzQ9A/1ZzHkJKb1P6yreOLSEh4KcxYPyrLRC1ll8nr5OlCx -CMhKkTnR6qBsdNV0XtdU2+N25hqW+Ma4ZeqsN/iiJVCGNOZGnvQuvCAGWF8+J/f/ -iHkC6gGdBJhogs4= +MIICVDCCAb2gAwIBAgIJANfHOBkZr8JOMA0GCSqGSIb3DQEBBQUAMF8xCzAJBgNV +BAYTAlhZMRcwFQYDVQQHEw5DYXN0bGUgQW50aHJheDEjMCEGA1UEChMaUHl0aG9u +IFNvZnR3YXJlIEZvdW5kYXRpb24xEjAQBgNVBAMTCWxvY2FsaG9zdDAeFw0xMDEw +MDgyMzAxNTZaFw0yMDEwMDUyMzAxNTZaMF8xCzAJBgNVBAYTAlhZMRcwFQYDVQQH +Ew5DYXN0bGUgQW50aHJheDEjMCEGA1UEChMaUHl0aG9uIFNvZnR3YXJlIEZvdW5k +YXRpb24xEjAQBgNVBAMTCWxvY2FsaG9zdDCBnzANBgkqhkiG9w0BAQEFAAOBjQAw +gYkCgYEA21vT5isq7F68amYuuNpSFlKDPrMUCa4YWYqZRt2OZ+/3NKaZ2xAiSwr7 +6MrQF70t5nLbSPpqE5+5VrS58SY+g/sXLiFd6AplH1wJZwh78DofbFYXUggktFMt +pTyiX8jtP66bkcPkDADA089RI1TQR6Ca+n7HFa7c1fabVV6i3zkCAwEAAaMYMBYw +FAYDVR0RBA0wC4IJbG9jYWxob3N0MA0GCSqGSIb3DQEBBQUAA4GBAHPctQBEQ4wd +BJ6+JcpIraopLn8BGhbjNWj40mmRqWB/NAWF6M5ne7KpGAu7tLeG4hb1zLaldK8G +lxy2GPSRF6LFS48dpEj2HbMv2nvv6xxalDMJ9+DicWgAKTQ6bcX2j3GUkCR0g/T1 +CRlNBAAlvhKzO7Clpf9l0YKBEfraJByX -----END CERTIFICATE----- diff --git a/lib-python/2.7/test/sha256.pem b/lib-python/2.7/test/sha256.pem --- a/lib-python/2.7/test/sha256.pem +++ b/lib-python/2.7/test/sha256.pem @@ -1,129 +1,128 @@ # Certificate chain for https://sha256.tbs-internet.com - 0 s:/C=FR/postalCode=14000/ST=Calvados/L=CAEN/street=22 rue de Bretagne/O=TBS INTERNET/OU=0002 440443810/OU=sha-256 production/CN=sha256.tbs-internet.com - i:/C=FR/ST=Calvados/L=Caen/O=TBS INTERNET/OU=Terms and Conditions: http://www.tbs-internet.com/CA/repository/OU=TBS INTERNET CA/CN=TBS X509 CA SGC + 0 s:/C=FR/postalCode=14000/ST=Calvados/L=CAEN/street=22 rue de Bretagne/O=TBS INTERNET/OU=0002 440443810/OU=Certificats TBS X509/CN=ecom.tbs-x509.com + i:/C=FR/ST=Calvados/L=Caen/O=TBS INTERNET/OU=Terms and Conditions: http://www.tbs-internet.com/CA/repository/OU=TBS INTERNET CA/CN=TBS X509 CA business -----BEGIN CERTIFICATE----- -MIIGXTCCBUWgAwIBAgIRAMmag+ygSAdxZsbyzYjhuW0wDQYJKoZIhvcNAQELBQAw -gcQxCzAJBgNVBAYTAkZSMREwDwYDVQQIEwhDYWx2YWRvczENMAsGA1UEBxMEQ2Fl +MIIGTjCCBTagAwIBAgIQOh3d9dNDPq1cSdJmEiMpqDANBgkqhkiG9w0BAQUFADCB +yTELMAkGA1UEBhMCRlIxETAPBgNVBAgTCENhbHZhZG9zMQ0wCwYDVQQHEwRDYWVu +MRUwEwYDVQQKEwxUQlMgSU5URVJORVQxSDBGBgNVBAsTP1Rlcm1zIGFuZCBDb25k +aXRpb25zOiBodHRwOi8vd3d3LnRicy1pbnRlcm5ldC5jb20vQ0EvcmVwb3NpdG9y +eTEYMBYGA1UECxMPVEJTIElOVEVSTkVUIENBMR0wGwYDVQQDExRUQlMgWDUwOSBD +QSBidXNpbmVzczAeFw0xMTAxMjUwMDAwMDBaFw0xMzAyMDUyMzU5NTlaMIHHMQsw +CQYDVQQGEwJGUjEOMAwGA1UEERMFMTQwMDAxETAPBgNVBAgTCENhbHZhZG9zMQ0w +CwYDVQQHEwRDQUVOMRswGQYDVQQJExIyMiBydWUgZGUgQnJldGFnbmUxFTATBgNV +BAoTDFRCUyBJTlRFUk5FVDEXMBUGA1UECxMOMDAwMiA0NDA0NDM4MTAxHTAbBgNV +BAsTFENlcnRpZmljYXRzIFRCUyBYNTA5MRowGAYDVQQDExFlY29tLnRicy14NTA5 +LmNvbTCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBAKRrlHUnJ++1lpcg +jtYco7cdmRe+EEfTmwPfCdfV3G1QfsTSvY6FfMpm/83pqHfT+4ANwr18wD9ZrAEN +G16mf9VdCGK12+TP7DmqeZyGIqlFFoahQnmb8EarvE43/1UeQ2CV9XmzwZvpqeli +LfXsFonawrY3H6ZnMwS64St61Z+9gdyuZ/RbsoZBbT5KUjDEG844QRU4OT1IGeEI +eY5NM5RNIh6ZNhVtqeeCxMS7afONkHQrOco73RdSTRck/Hj96Ofl3MHNHryr+AMK +DGFk1kLCZGpPdXtkxXvaDeQoiYDlil26CWc+YK6xyDPMdsWvoG14ZLyCpzMXA7/7 +4YAQRH0CAwEAAaOCAjAwggIsMB8GA1UdIwQYMBaAFBoJBMz5CY+7HqDO1KQUf0vV +I1jNMB0GA1UdDgQWBBQgOU8HsWzbmD4WZP5Wtdw7jca2WDAOBgNVHQ8BAf8EBAMC +BaAwDAYDVR0TAQH/BAIwADAdBgNVHSUEFjAUBggrBgEFBQcDAQYIKwYBBQUHAwIw +TAYDVR0gBEUwQzBBBgsrBgEEAYDlNwIBATAyMDAGCCsGAQUFBwIBFiRodHRwczov +L3d3dy50YnMtaW50ZXJuZXQuY29tL0NBL0NQUzEwdwYDVR0fBHAwbjA3oDWgM4Yx +aHR0cDovL2NybC50YnMtaW50ZXJuZXQuY29tL1RCU1g1MDlDQWJ1c2luZXNzLmNy +bDAzoDGgL4YtaHR0cDovL2NybC50YnMteDUwOS5jb20vVEJTWDUwOUNBYnVzaW5l +c3MuY3JsMIGwBggrBgEFBQcBAQSBozCBoDA9BggrBgEFBQcwAoYxaHR0cDovL2Ny +dC50YnMtaW50ZXJuZXQuY29tL1RCU1g1MDlDQWJ1c2luZXNzLmNydDA5BggrBgEF +BQcwAoYtaHR0cDovL2NydC50YnMteDUwOS5jb20vVEJTWDUwOUNBYnVzaW5lc3Mu +Y3J0MCQGCCsGAQUFBzABhhhodHRwOi8vb2NzcC50YnMteDUwOS5jb20wMwYDVR0R +BCwwKoIRZWNvbS50YnMteDUwOS5jb22CFXd3dy5lY29tLnRicy14NTA5LmNvbTAN +BgkqhkiG9w0BAQUFAAOCAQEArT4NHfbY87bGAw8lPV4DmHlmuDuVp/y7ltO3Ynse +3Rz8RxW2AzuO0Oy2F0Cu4yWKtMyEyMXyHqWtae7ElRbdTu5w5GwVBLJHClCzC8S9 +SpgMMQTx3Rgn8vjkHuU9VZQlulZyiPK7yunjc7c310S9FRZ7XxOwf8Nnx4WnB+No +WrfApzhhQl31w+RyrNxZe58hCfDDHmevRvwLjQ785ZoQXJDj2j3qAD4aI2yB8lB5 +oaE1jlCJzC7Kmz/Y9jzfmv/zAs1LQTm9ktevv4BTUFaGjv9jxnQ1xnS862ZiouLW +zZYIlYPf4F6JjXGiIQgQRglILUfq3ftJd9/ok9W9ZF8h8w== +-----END CERTIFICATE----- + 1 s:/C=FR/ST=Calvados/L=Caen/O=TBS INTERNET/OU=Terms and Conditions: http://www.tbs-internet.com/CA/repository/OU=TBS INTERNET CA/CN=TBS X509 CA business + i:/C=SE/O=AddTrust AB/OU=AddTrust External TTP Network/CN=AddTrust External CA Root +-----BEGIN CERTIFICATE----- +MIIFPzCCBCegAwIBAgIQDlBz/++iRSmLDeVRHT/hADANBgkqhkiG9w0BAQUFADBv +MQswCQYDVQQGEwJTRTEUMBIGA1UEChMLQWRkVHJ1c3QgQUIxJjAkBgNVBAsTHUFk +ZFRydXN0IEV4dGVybmFsIFRUUCBOZXR3b3JrMSIwIAYDVQQDExlBZGRUcnVzdCBF +eHRlcm5hbCBDQSBSb290MB4XDTA1MTIwMTAwMDAwMFoXDTE5MDcwOTE4MTkyMlow +gckxCzAJBgNVBAYTAkZSMREwDwYDVQQIEwhDYWx2YWRvczENMAsGA1UEBxMEQ2Fl bjEVMBMGA1UEChMMVEJTIElOVEVSTkVUMUgwRgYDVQQLEz9UZXJtcyBhbmQgQ29u ZGl0aW9uczogaHR0cDovL3d3dy50YnMtaW50ZXJuZXQuY29tL0NBL3JlcG9zaXRv -cnkxGDAWBgNVBAsTD1RCUyBJTlRFUk5FVCBDQTEYMBYGA1UEAxMPVEJTIFg1MDkg -Q0EgU0dDMB4XDTEwMDIxODAwMDAwMFoXDTEyMDIxOTIzNTk1OVowgcsxCzAJBgNV -BAYTAkZSMQ4wDAYDVQQREwUxNDAwMDERMA8GA1UECBMIQ2FsdmFkb3MxDTALBgNV -BAcTBENBRU4xGzAZBgNVBAkTEjIyIHJ1ZSBkZSBCcmV0YWduZTEVMBMGA1UEChMM -VEJTIElOVEVSTkVUMRcwFQYDVQQLEw4wMDAyIDQ0MDQ0MzgxMDEbMBkGA1UECxMS -c2hhLTI1NiBwcm9kdWN0aW9uMSAwHgYDVQQDExdzaGEyNTYudGJzLWludGVybmV0 -LmNvbTCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBAKbuM8VT7f0nntwu -N3F7v9KIBlhKNAxqCrziOXU5iqUt8HrQB3DtHbdmII+CpVUlwlmepsx6G+srEZ9a -MIGAy0nxi5aLb7watkyIdPjJTMvTUBQ/+RPWzt5JtYbbY9BlJ+yci0dctP74f4NU -ISLtlrEjUbf2gTohLrcE01TfmOF6PDEbB5PKDi38cB3NzKfizWfrOaJW6Q1C1qOJ -y4/4jkUREX1UFUIxzx7v62VfjXSGlcjGpBX1fvtABQOSLeE0a6gciDZs1REqroFf -5eXtqYphpTa14Z83ITXMfgg5Nze1VtMnzI9Qx4blYBw4dgQVEuIsYr7FDBOITDzc -VEVXZx0CAwEAAaOCAj8wggI7MB8GA1UdIwQYMBaAFAdEdoWTKLx/bXjSCuv6TEvf -2YIfMB0GA1UdDgQWBBSJKI/AYVI9RQNY0QPIqc8ej2QivTAOBgNVHQ8BAf8EBAMC -BaAwDAYDVR0TAQH/BAIwADA0BgNVHSUELTArBggrBgEFBQcDAQYIKwYBBQUHAwIG -CisGAQQBgjcKAwMGCWCGSAGG+EIEATBMBgNVHSAERTBDMEEGCysGAQQBgOU3AgQB -MDIwMAYIKwYBBQUHAgEWJGh0dHBzOi8vd3d3LnRicy1pbnRlcm5ldC5jb20vQ0Ev -Q1BTNDBtBgNVHR8EZjBkMDKgMKAuhixodHRwOi8vY3JsLnRicy1pbnRlcm5ldC5j -b20vVEJTWDUwOUNBU0dDLmNybDAuoCygKoYoaHR0cDovL2NybC50YnMteDUwOS5j -b20vVEJTWDUwOUNBU0dDLmNybDCBpgYIKwYBBQUHAQEEgZkwgZYwOAYIKwYBBQUH -MAKGLGh0dHA6Ly9jcnQudGJzLWludGVybmV0LmNvbS9UQlNYNTA5Q0FTR0MuY3J0 -MDQGCCsGAQUFBzAChihodHRwOi8vY3J0LnRicy14NTA5LmNvbS9UQlNYNTA5Q0FT -R0MuY3J0MCQGCCsGAQUFBzABhhhodHRwOi8vb2NzcC50YnMteDUwOS5jb20wPwYD -VR0RBDgwNoIXc2hhMjU2LnRicy1pbnRlcm5ldC5jb22CG3d3dy5zaGEyNTYudGJz -LWludGVybmV0LmNvbTANBgkqhkiG9w0BAQsFAAOCAQEAA5NL0D4QSqhErhlkdPmz -XtiMvdGL+ZehM4coTRIpasM/Agt36Rc0NzCvnQwKE+wkngg1Gy2qe7Q0E/ziqBtB -fZYzdVgu1zdiL4kTaf+wFKYAFGsFbyeEmXysy+CMwaNoF2vpSjCU1UD56bEnTX/W -fxVZYxtBQUpnu2wOsm8cDZuZRv9XrYgAhGj9Tt6F0aVHSDGn59uwShG1+BVF/uju -SCyPTTjL1oc7YElJUzR/x4mQJYvtQI8gDIDAGEOs7v3R/gKa5EMfbUQUI4C84UbI -Yz09Jdnws/MkC/Hm1BZEqk89u7Hvfv+oHqEb0XaUo0TDfsxE0M1sMdnLb91QNQBm -UQ== ------END CERTIFICATE----- - 1 s:/C=FR/ST=Calvados/L=Caen/O=TBS INTERNET/OU=Terms and Conditions: http://www.tbs-internet.com/CA/repository/OU=TBS INTERNET CA/CN=TBS X509 CA SGC - i:/C=SE/O=AddTrust AB/OU=AddTrust External TTP Network/CN=AddTrust External CA Root ------BEGIN CERTIFICATE----- -MIIFVjCCBD6gAwIBAgIQXpDZ0ETJMV02WTx3GTnhhTANBgkqhkiG9w0BAQUFADBv -MQswCQYDVQQGEwJTRTEUMBIGA1UEChMLQWRkVHJ1c3QgQUIxJjAkBgNVBAsTHUFk -ZFRydXN0IEV4dGVybmFsIFRUUCBOZXR3b3JrMSIwIAYDVQQDExlBZGRUcnVzdCBF -eHRlcm5hbCBDQSBSb290MB4XDTA1MTIwMTAwMDAwMFoXDTE5MDYyNDE5MDYzMFow -gcQxCzAJBgNVBAYTAkZSMREwDwYDVQQIEwhDYWx2YWRvczENMAsGA1UEBxMEQ2Fl -bjEVMBMGA1UEChMMVEJTIElOVEVSTkVUMUgwRgYDVQQLEz9UZXJtcyBhbmQgQ29u -ZGl0aW9uczogaHR0cDovL3d3dy50YnMtaW50ZXJuZXQuY29tL0NBL3JlcG9zaXRv -cnkxGDAWBgNVBAsTD1RCUyBJTlRFUk5FVCBDQTEYMBYGA1UEAxMPVEJTIFg1MDkg -Q0EgU0dDMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAsgOkO3f7wzN6 -rOjg45tR5vjBfzK7qmV9IBxb/QW9EEXxG+E7FNhZqQLtwGBKoSsHTnQqV75wWMk0 -9tinWvftBkSpj5sTi/8cbzJfUvTSVYh3Qxv6AVVjMMH/ruLjE6y+4PoaPs8WoYAQ -ts5R4Z1g8c/WnTepLst2x0/Wv7GmuoQi+gXvHU6YrBiu7XkeYhzc95QdviWSJRDk -owhb5K43qhcvjRmBfO/paGlCliDGZp8mHwrI21mwobWpVjTxZRwYO3bd4+TGcI4G -Ie5wmHwE8F7SK1tgSqbBacKjDa93j7txKkfz/Yd2n7TGqOXiHPsJpG655vrKtnXk -9vs1zoDeJQIDAQABo4IBljCCAZIwHQYDVR0OBBYEFAdEdoWTKLx/bXjSCuv6TEvf -2YIfMA4GA1UdDwEB/wQEAwIBBjASBgNVHRMBAf8ECDAGAQH/AgEAMCAGA1UdJQQZ -MBcGCisGAQQBgjcKAwMGCWCGSAGG+EIEATAYBgNVHSAEETAPMA0GCysGAQQBgOU3 -AgQBMHsGA1UdHwR0MHIwOKA2oDSGMmh0dHA6Ly9jcmwuY29tb2RvY2EuY29tL0Fk -ZFRydXN0RXh0ZXJuYWxDQVJvb3QuY3JsMDagNKAyhjBodHRwOi8vY3JsLmNvbW9k -by5uZXQvQWRkVHJ1c3RFeHRlcm5hbENBUm9vdC5jcmwwgYAGCCsGAQUFBwEBBHQw -cjA4BggrBgEFBQcwAoYsaHR0cDovL2NydC5jb21vZG9jYS5jb20vQWRkVHJ1c3RV -VE5TR0NDQS5jcnQwNgYIKwYBBQUHMAKGKmh0dHA6Ly9jcnQuY29tb2RvLm5ldC9B -ZGRUcnVzdFVUTlNHQ0NBLmNydDARBglghkgBhvhCAQEEBAMCAgQwDQYJKoZIhvcN -AQEFBQADggEBAK2zEzs+jcIrVK9oDkdDZNvhuBYTdCfpxfFs+OAujW0bIfJAy232 -euVsnJm6u/+OrqKudD2tad2BbejLLXhMZViaCmK7D9nrXHx4te5EP8rL19SUVqLY -1pTnv5dhNgEgvA7n5lIzDSYs7yRLsr7HJsYPr6SeYSuZizyX1SNz7ooJ32/F3X98 -RB0Mlc/E0OyOrkQ9/y5IrnpnaSora8CnUrV5XNOg+kyCz9edCyx4D5wXYcwZPVWz -8aDqquESrezPyjtfi4WRO4s/VD3HLZvOxzMrWAVYCDG9FxaOhF0QGuuG1F7F3GKV -v6prNyCl016kRl2j1UT+a7gLd8fA25A4C9E= +cnkxGDAWBgNVBAsTD1RCUyBJTlRFUk5FVCBDQTEdMBsGA1UEAxMUVEJTIFg1MDkg +Q0EgYnVzaW5lc3MwggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQDB1PAU +qudCcz3tmyGcf+u6EkZqonKKHrV4gZYbvVkIRojmmlhfi/jwvpHvo8bqSt/9Rj5S +jhCDW0pcbI+IPPtD1Jy+CHNSfnMqVDy6CKQ3p5maTzCMG6ZT+XjnvcND5v+FtaiB +xk1iCX6uvt0jeUtdZvYbyytsSDE6c3Y5//wRxOF8tM1JxibwO3pyER26jbbN2gQz +m/EkdGjLdJ4svPk23WDAvQ6G0/z2LcAaJB+XLfqRwfQpHQvfKa1uTi8PivC8qtip +rmNQMMPMjxSK2azX8cKjjTDJiUKaCb4VHlJDWKEsCFRpgJAoAuX8f7Yfs1M4esGo +sWb3PGspK3O22uIlAgMBAAGjggF6MIIBdjAdBgNVHQ4EFgQUGgkEzPkJj7seoM7U +pBR/S9UjWM0wDgYDVR0PAQH/BAQDAgEGMBIGA1UdEwEB/wQIMAYBAf8CAQAwGAYD +VR0gBBEwDzANBgsrBgEEAYDlNwIBATB7BgNVHR8EdDByMDigNqA0hjJodHRwOi8v +Y3JsLmNvbW9kb2NhLmNvbS9BZGRUcnVzdEV4dGVybmFsQ0FSb290LmNybDA2oDSg +MoYwaHR0cDovL2NybC5jb21vZG8ubmV0L0FkZFRydXN0RXh0ZXJuYWxDQVJvb3Qu +Y3JsMIGGBggrBgEFBQcBAQR6MHgwOwYIKwYBBQUHMAKGL2h0dHA6Ly9jcnQuY29t +b2RvY2EuY29tL0FkZFRydXN0VVROU2VydmVyQ0EuY3J0MDkGCCsGAQUFBzAChi1o +dHRwOi8vY3J0LmNvbW9kby5uZXQvQWRkVHJ1c3RVVE5TZXJ2ZXJDQS5jcnQwEQYJ +YIZIAYb4QgEBBAQDAgIEMA0GCSqGSIb3DQEBBQUAA4IBAQA7mqrMgk/MrE6QnbNA +h4nRCn2ti4bg4w2C3lB6bSvRPnYwuNw9Jb8vuKkNFzRDxNJXqVDZdfFW5CVQJuyd +nfAx83+wk+spzvFaE1KhFYfN9G9pQfXUfvDRoIcJgPEKUXL1wRiOG+IjU3VVI8pg +IgqHkr7ylln5i5zCiFAPuIJmYUSFg/gxH5xkCNcjJqqrHrHatJr6Qrrke93joupw +oU1njfAcZtYp6fbiK6u2b1pJqwkVBE8RsfLnPhRj+SFbpvjv8Od7o/ieJhFIYQNU +k2jX2u8qZnAiNw93LZW9lpYjtuvMXq8QQppENNja5b53q7UwI+lU7ZGjZ7quuESp +J6/5 -----END CERTIFICATE----- 2 s:/C=SE/O=AddTrust AB/OU=AddTrust External TTP Network/CN=AddTrust External CA Root - i:/C=US/ST=UT/L=Salt Lake City/O=The USERTRUST Network/OU=http://www.usertrust.com/CN=UTN - DATACorp SGC + i:/C=US/ST=UT/L=Salt Lake City/O=The USERTRUST Network/OU=http://www.usertrust.com/CN=UTN-USERFirst-Hardware -----BEGIN CERTIFICATE----- -MIIEZjCCA06gAwIBAgIQUSYKkxzif5zDpV954HKugjANBgkqhkiG9w0BAQUFADCB -kzELMAkGA1UEBhMCVVMxCzAJBgNVBAgTAlVUMRcwFQYDVQQHEw5TYWx0IExha2Ug +MIIETzCCAzegAwIBAgIQHM5EYpUZep1jUvnyI6m2mDANBgkqhkiG9w0BAQUFADCB +lzELMAkGA1UEBhMCVVMxCzAJBgNVBAgTAlVUMRcwFQYDVQQHEw5TYWx0IExha2Ug Q2l0eTEeMBwGA1UEChMVVGhlIFVTRVJUUlVTVCBOZXR3b3JrMSEwHwYDVQQLExho -dHRwOi8vd3d3LnVzZXJ0cnVzdC5jb20xGzAZBgNVBAMTElVUTiAtIERBVEFDb3Jw -IFNHQzAeFw0wNTA2MDcwODA5MTBaFw0xOTA2MjQxOTA2MzBaMG8xCzAJBgNVBAYT -AlNFMRQwEgYDVQQKEwtBZGRUcnVzdCBBQjEmMCQGA1UECxMdQWRkVHJ1c3QgRXh0 -ZXJuYWwgVFRQIE5ldHdvcmsxIjAgBgNVBAMTGUFkZFRydXN0IEV4dGVybmFsIENB -IFJvb3QwggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQC39xoz5vIABC05 -4E5b7R+8bA/Ntfojts7emxEzl6QpTH2Tn71KvJPtAxrjj8/lbVBa1pcplFqAsEl6 -2y6V/bjKvzc4LR4+kUGtcFbH8E8/6DKedMrIkFTpxl8PeJ2aQDwOrGGqXhSPnoeh -alDc15pOrwWzpnGUnHGzUGAKxxOdOAeGAqjpqGkmGJCrTLBPI6s6T4TY386f4Wlv -u9dC12tE5Met7m1BX3JacQg3s3llpFmglDf3AC8NwpJy2tA4ctsUqEXEXSp9t7TW -xO6szRNEt8kr3UMAJfphuWlqWCMRt6czj1Z1WfXNKddGtworZbbTQm8Vsrh7++/p -XVPVNFonAgMBAAGjgdgwgdUwHwYDVR0jBBgwFoAUUzLRs89/+uDxoF2FTpLSnkUd -tE8wHQYDVR0OBBYEFK29mHo0tCb3+sQmVO8DveAky1QaMA4GA1UdDwEB/wQEAwIB -BjAPBgNVHRMBAf8EBTADAQH/MBEGCWCGSAGG+EIBAQQEAwIBAjAgBgNVHSUEGTAX -BgorBgEEAYI3CgMDBglghkgBhvhCBAEwPQYDVR0fBDYwNDAyoDCgLoYsaHR0cDov -L2NybC51c2VydHJ1c3QuY29tL1VUTi1EQVRBQ29ycFNHQy5jcmwwDQYJKoZIhvcN -AQEFBQADggEBAMbuUxdoFLJRIh6QWA2U/b3xcOWGLcM2MY9USEbnLQg3vGwKYOEO -rVE04BKT6b64q7gmtOmWPSiPrmQH/uAB7MXjkesYoPF1ftsK5p+R26+udd8jkWjd -FwBaS/9kbHDrARrQkNnHptZt9hPk/7XJ0h4qy7ElQyZ42TCbTg0evmnv3+r+LbPM -+bDdtRTKkdSytaX7ARmjR3mfnYyVhzT4HziS2jamEfpr62vp3EV4FTkG101B5CHI -3C+H0be/SGB1pWLLJN47YaApIKa+xWycxOkKaSLvkTr6Jq/RW0GnOuL4OAdCq8Fb -+M5tug8EPzI0rNwEKNdwMBQmBsTkm5jVz3g= +dHRwOi8vd3d3LnVzZXJ0cnVzdC5jb20xHzAdBgNVBAMTFlVUTi1VU0VSRmlyc3Qt +SGFyZHdhcmUwHhcNMDUwNjA3MDgwOTEwWhcNMTkwNzA5MTgxOTIyWjBvMQswCQYD +VQQGEwJTRTEUMBIGA1UEChMLQWRkVHJ1c3QgQUIxJjAkBgNVBAsTHUFkZFRydXN0 +IEV4dGVybmFsIFRUUCBOZXR3b3JrMSIwIAYDVQQDExlBZGRUcnVzdCBFeHRlcm5h +bCBDQSBSb290MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAt/caM+by +AAQtOeBOW+0fvGwPzbX6I7bO3psRM5ekKUx9k5+9SryT7QMa44/P5W1QWtaXKZRa +gLBJetsulf24yr83OC0ePpFBrXBWx/BPP+gynnTKyJBU6cZfD3idmkA8Dqxhql4U +j56HoWpQ3NeaTq8Fs6ZxlJxxs1BgCscTnTgHhgKo6ahpJhiQq0ywTyOrOk+E2N/O +n+Fpb7vXQtdrROTHre5tQV9yWnEIN7N5ZaRZoJQ39wAvDcKSctrQOHLbFKhFxF0q +fbe01sTurM0TRLfJK91DACX6YblpalgjEbenM49WdVn1zSnXRrcKK2W200JvFbK4 +e/vv6V1T1TRaJwIDAQABo4G9MIG6MB8GA1UdIwQYMBaAFKFyXyYbKJhDlV0HN9WF +lp1L0sNFMB0GA1UdDgQWBBStvZh6NLQm9/rEJlTvA73gJMtUGjAOBgNVHQ8BAf8E +BAMCAQYwDwYDVR0TAQH/BAUwAwEB/zARBglghkgBhvhCAQEEBAMCAQIwRAYDVR0f +BD0wOzA5oDegNYYzaHR0cDovL2NybC51c2VydHJ1c3QuY29tL1VUTi1VU0VSRmly +c3QtSGFyZHdhcmUuY3JsMA0GCSqGSIb3DQEBBQUAA4IBAQByQhANOs4kClrwF8BW +onvUOGCSjRK52zYZgDXYNjDtmr5rJ6NyPFDNn+JxkLpjYetIFMTbSRe679Bt8m7a +gIAoQYFQtxMuyLnJegB2aEbQiIxh/tC21UcFF7ktdnDoTlA6w3pLuvunaI84Of3o +2YBrhzkTbCfaYk5JRlTpudW9DkUkHBsyx3nknPKnplkIGaK0jgn8E0n+SFabYaHk +I9LroYT/+JtLefh9lgBdAgVv0UPbzoGfuDsrk/Zh+UrgbLFpHoVnElhzbkh64Z0X +OGaJunQc68cCZu5HTn/aK7fBGMcVflRCXLVEQpU9PIAdGA8Ynvg684t8GMaKsRl1 +jIGZ -----END CERTIFICATE----- - 3 s:/C=US/ST=UT/L=Salt Lake City/O=The USERTRUST Network/OU=http://www.usertrust.com/CN=UTN - DATACorp SGC - i:/C=US/ST=UT/L=Salt Lake City/O=The USERTRUST Network/OU=http://www.usertrust.com/CN=UTN - DATACorp SGC + 3 s:/C=US/ST=UT/L=Salt Lake City/O=The USERTRUST Network/OU=http://www.usertrust.com/CN=UTN-USERFirst-Hardware + i:/C=US/ST=UT/L=Salt Lake City/O=The USERTRUST Network/OU=http://www.usertrust.com/CN=UTN-USERFirst-Hardware -----BEGIN CERTIFICATE----- -MIIEXjCCA0agAwIBAgIQRL4Mi1AAIbQR0ypoBqmtaTANBgkqhkiG9w0BAQUFADCB -kzELMAkGA1UEBhMCVVMxCzAJBgNVBAgTAlVUMRcwFQYDVQQHEw5TYWx0IExha2Ug +MIIEdDCCA1ygAwIBAgIQRL4Mi1AAJLQR0zYq/mUK/TANBgkqhkiG9w0BAQUFADCB +lzELMAkGA1UEBhMCVVMxCzAJBgNVBAgTAlVUMRcwFQYDVQQHEw5TYWx0IExha2Ug Q2l0eTEeMBwGA1UEChMVVGhlIFVTRVJUUlVTVCBOZXR3b3JrMSEwHwYDVQQLExho -dHRwOi8vd3d3LnVzZXJ0cnVzdC5jb20xGzAZBgNVBAMTElVUTiAtIERBVEFDb3Jw -IFNHQzAeFw05OTA2MjQxODU3MjFaFw0xOTA2MjQxOTA2MzBaMIGTMQswCQYDVQQG -EwJVUzELMAkGA1UECBMCVVQxFzAVBgNVBAcTDlNhbHQgTGFrZSBDaXR5MR4wHAYD -VQQKExVUaGUgVVNFUlRSVVNUIE5ldHdvcmsxITAfBgNVBAsTGGh0dHA6Ly93d3cu -dXNlcnRydXN0LmNvbTEbMBkGA1UEAxMSVVROIC0gREFUQUNvcnAgU0dDMIIBIjAN -BgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEA3+5YEKIrblXEjr8uRgnn4AgPLit6 -E5Qbvfa2gI5lBZMAHryv4g+OGQ0SR+ysraP6LnD43m77VkIVni5c7yPeIbkFdicZ -D0/Ww5y0vpQZY/KmEQrrU0icvvIpOxboGqBMpsn0GFlowHDyUwDAXlCCpVZvNvlK -4ESGoE1O1kduSUrLZ9emxAW5jh70/P/N5zbgnAVssjMiFdC04MwXwLLA9P4yPykq -lXvY8qdOD1R8oQ2AswkDwf9c3V6aPryuvEeKaq5xyh+xKrhfQgUL7EYw0XILyulW -bfXv33i+Ybqypa4ETLyorGkVl73v67SMvzX41MPRKA5cOp9wGDMgd8SirwIDAQAB -o4GrMIGoMAsGA1UdDwQEAwIBxjAPBgNVHRMBAf8EBTADAQH/MB0GA1UdDgQWBBRT -MtGzz3/64PGgXYVOktKeRR20TzA9BgNVHR8ENjA0MDKgMKAuhixodHRwOi8vY3Js -LnVzZXJ0cnVzdC5jb20vVVROLURBVEFDb3JwU0dDLmNybDAqBgNVHSUEIzAhBggr -BgEFBQcDAQYKKwYBBAGCNwoDAwYJYIZIAYb4QgQBMA0GCSqGSIb3DQEBBQUAA4IB -AQAnNZcAiosovcYzMB4p/OL31ZjUQLtgyr+rFywJNn9Q+kHcrpY6CiM+iVnJowft -Gzet/Hy+UUla3joKVAgWRcKZsYfNjGjgaQPpxE6YsjuMFrMOoAyYUJuTqXAJyCyj -j98C5OBxOvG0I3KgqgHf35g+FFCgMSa9KOlaMCZ1+XtgHI3zzVAmbQQnmt/VDUVH -KWss5nbZqSl9Mt3JNjy9rjXxEZ4du5A/EkdOjtd+D2JzHVImOBwYSf0wdJrE5SIv -2MCN7ZF6TACPcn9d2t0bi0Vr591pl6jFVkwPDPafepE39peC4N1xaf92P2BNPM/3 -mfnGV/TJVTl4uix5yaaIK/QI +dHRwOi8vd3d3LnVzZXJ0cnVzdC5jb20xHzAdBgNVBAMTFlVUTi1VU0VSRmlyc3Qt +SGFyZHdhcmUwHhcNOTkwNzA5MTgxMDQyWhcNMTkwNzA5MTgxOTIyWjCBlzELMAkG +A1UEBhMCVVMxCzAJBgNVBAgTAlVUMRcwFQYDVQQHEw5TYWx0IExha2UgQ2l0eTEe +MBwGA1UEChMVVGhlIFVTRVJUUlVTVCBOZXR3b3JrMSEwHwYDVQQLExhodHRwOi8v +d3d3LnVzZXJ0cnVzdC5jb20xHzAdBgNVBAMTFlVUTi1VU0VSRmlyc3QtSGFyZHdh +cmUwggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQCx98M4P7Sof885glFn +0G2f0v9Y8+efK+wNiVSZuTiZFvfgIXlIwrthdBKWHTxqctU8EGc6Oe0rE81m65UJ +M6Rsl7HoxuzBdXmcRl6Nq9Bq/bkqVRcQVLMZ8Jr28bFdtqdt++BxF2uiiPsA3/4a +MXcMmgF6sTLjKwEHOG7DpV4jvEWbe1DByTCP2+UretNb+zNAHqDVmBe8i4fDidNd +oI6yqqr2jmmIBsX6iSHzCJ1pLgkzmykNRg+MzEk0sGlRvfkGzWitZky8PqxhvQqI +DsjfPe58BEydCl5rkdbux+0ojatNh4lz0G6k0B4WixThdkQDf2Os5M1JnMWS9Ksy +oUhbAgMBAAGjgbkwgbYwCwYDVR0PBAQDAgHGMA8GA1UdEwEB/wQFMAMBAf8wHQYD +VR0OBBYEFKFyXyYbKJhDlV0HN9WFlp1L0sNFMEQGA1UdHwQ9MDswOaA3oDWGM2h0 +dHA6Ly9jcmwudXNlcnRydXN0LmNvbS9VVE4tVVNFUkZpcnN0LUhhcmR3YXJlLmNy +bDAxBgNVHSUEKjAoBggrBgEFBQcDAQYIKwYBBQUHAwUGCCsGAQUFBwMGBggrBgEF +BQcDBzANBgkqhkiG9w0BAQUFAAOCAQEARxkP3nTGmZev/K0oXnWO6y1n7k57K9cM +//bey1WiCuFMVGWTYGufEpytXoMs61quwOQt9ABjHbjAbPLPSbtNk28Gpgoiskli +CE7/yMgUsogWXecB5BKV5UU0s4tpvc+0hY91UZ59Ojg6FEgSxvunOxqNDYJAB+gE +CJChicsZUN/KHAG8HQQZexB2lzvukJDKxA4fFm517zP4029bHpbj4HR3dHuKom4t +3XbWOTCC8KucUvIqx69JXn7HaOWCgchqJ/kniCrVWFCVH/A7HFe7fRQ5YiuayZSS +KqMiDP+JJn1fIytH1xUdqWqeUQ0qUZ6B+dQ7XnASfxAynB67nfhmqA== -----END CERTIFICATE----- diff --git a/lib-python/2.7/test/test_ssl.py b/lib-python/2.7/test/test_ssl.py --- a/lib-python/2.7/test/test_ssl.py +++ b/lib-python/2.7/test/test_ssl.py @@ -111,13 +111,12 @@ if test_support.verbose: sys.stdout.write("\n" + pprint.pformat(p) + "\n") self.assertEqual(p['subject'], - ((('countryName', u'US'),), - (('stateOrProvinceName', u'Delaware'),), - (('localityName', u'Wilmington'),), - (('organizationName', u'Python Software Foundation'),), - (('organizationalUnitName', u'SSL'),), - (('commonName', u'somemachine.python.org'),)), + ((('countryName', 'XY'),), + (('localityName', 'Castle Anthrax'),), + (('organizationName', 'Python Software Foundation'),), + (('commonName', 'localhost'),)) ) + self.assertEqual(p['subjectAltName'], (('DNS', 'localhost'),)) # Issue #13034: the subjectAltName in some certificates # (notably projects.developer.nokia.com:443) wasn't parsed p = ssl._ssl._test_decode_cert(NOKIACERT) diff --git a/lib_pypy/numpy.py b/lib_pypy/numpy.py --- a/lib_pypy/numpy.py +++ b/lib_pypy/numpy.py @@ -1,5 +1,12 @@ -raise ImportError( - "The 'numpy' module of PyPy is in-development and not complete. " - "To try it out anyway, you can either import from 'numpypy', " - "or just write 'import numpypy' first in your program and then " - "import from 'numpy' as usual.") +import warnings +import sys +if 'numpypy' not in sys.modules: + warnings.warn( + "The 'numpy' module of PyPy is in-development and not complete. " + "To avoid this warning, write 'import numpypy as numpy'. ", + UserWarning) # XXX is this the best warning type? + +from numpypy import * +import numpypy +__all__ = numpypy.__all__ +del numpypy diff --git a/lib_pypy/numpypy/__init__.py b/lib_pypy/numpypy/__init__.py --- a/lib_pypy/numpypy/__init__.py +++ b/lib_pypy/numpypy/__init__.py @@ -6,9 +6,19 @@ from __builtin__ import bool, int, long, float, complex, object, unicode, str from core import abs, max, min -__all__ = [] +__version__ = '1.7.0' + +import os +def get_include(): + head, tail = os.path.split(os.path.dirname(os.path.abspath(__file__))) + return os.path.join(head, '../include') + + +__all__ = ['__version__', 'get_include'] __all__ += core.__all__ __all__ += lib.__all__ -import sys -sys.modules.setdefault('numpy', sys.modules['numpypy']) +#import sys +#sys.modules.setdefault('numpy', sys.modules['numpypy']) + + diff --git a/lib_pypy/numpypy/core/fromnumeric.py b/lib_pypy/numpypy/core/fromnumeric.py --- a/lib_pypy/numpypy/core/fromnumeric.py +++ b/lib_pypy/numpypy/core/fromnumeric.py @@ -1133,7 +1133,13 @@ (array([1, 1, 1, 2, 2, 2]), array([0, 1, 2, 0, 1, 2])) """ - raise NotImplementedError('Waiting on interp level method') + try: + nonzero = a.nonzero + except AttributeError: + res = _wrapit(a, 'nonzero') + else: + res = nonzero() + return res def shape(a): diff --git a/pypy/doc/how-to-release.rst b/pypy/doc/how-to-release.rst --- a/pypy/doc/how-to-release.rst +++ b/pypy/doc/how-to-release.rst @@ -25,6 +25,7 @@ necessary; also update the version number in pypy/doc/conf.py, and in pypy/doc/index.rst * update pypy/doc/contributor.rst (and possibly LICENSE) + pypy/doc/tool/makecontributor.py generates the list of contributors * rename pypy/doc/whatsnew_head.rst to whatsnew_VERSION.rst and create a fresh whatsnew_head.rst after the release * update README diff --git a/pypy/doc/whatsnew-head.rst b/pypy/doc/whatsnew-head.rst --- a/pypy/doc/whatsnew-head.rst +++ b/pypy/doc/whatsnew-head.rst @@ -52,6 +52,10 @@ .. branch: ndarray-subtype Allow subclassing ndarray, i.e. matrix +.. branch: pypy-pyarray +Implement much of numpy's c api in cpyext, allows (slow) access to ndarray +from c + .. branch: kill-ootype .. branch: fast-slowpath @@ -97,3 +101,5 @@ Use subclasses of SpaceOperation instead of SpaceOperator objects. Random cleanups in flowspace. +.. branch: file-support-in-rpython +make open() and friends rpython diff --git a/pypy/module/_pypyjson/test/test__pypyjson.py b/pypy/module/_pypyjson/test/test__pypyjson.py --- a/pypy/module/_pypyjson/test/test__pypyjson.py +++ b/pypy/module/_pypyjson/test/test__pypyjson.py @@ -1,5 +1,5 @@ # -*- encoding: utf-8 -*- -import py +import py, sys from pypy.module._pypyjson.interp_decoder import JSONDecoder def test_skip_whitespace(): @@ -16,6 +16,9 @@ class AppTest(object): spaceconfig = {"objspace.usemodules._pypyjson": True} + def setup_class(cls): + cls.w_run_on_16bit = cls.space.wrap(sys.maxunicode == 65535) + def test_raise_on_unicode(self): import _pypyjson raises(TypeError, _pypyjson.loads, u"42") @@ -178,11 +181,11 @@ raises(ValueError, "_pypyjson.loads('[1: 2]')") raises(ValueError, "_pypyjson.loads('[1, 2')") raises(ValueError, """_pypyjson.loads('["extra comma",]')""") - + def test_unicode_surrogate_pair(self): + if self.run_on_16bit: + skip("XXX fix me or mark definitely skipped") import _pypyjson expected = u'z\U0001d120x' res = _pypyjson.loads('"z\\ud834\\udd20x"') assert res == expected - - 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 @@ -399,7 +399,7 @@ proto = libssl_SSL_CIPHER_get_version(current) if proto: - w_proto = space.wrap(rffi.charp2str(name)) + w_proto = space.wrap(rffi.charp2str(proto)) else: w_proto = space.w_None @@ -476,15 +476,15 @@ w_serial = space.wrap(rffi.charpsize2str(buf, length)) space.setitem(w_retval, space.wrap("serialNumber"), w_serial) - libssl_BIO_reset(biobuf) - notBefore = libssl_X509_get_notBefore(certificate) - libssl_ASN1_TIME_print(biobuf, notBefore) - with lltype.scoped_alloc(rffi.CCHARP.TO, 100) as buf: - length = libssl_BIO_gets(biobuf, buf, 99) - if length < 0: - raise _ssl_seterror(space, None, length) - w_date = space.wrap(rffi.charpsize2str(buf, length)) - space.setitem(w_retval, space.wrap("notBefore"), w_date) + libssl_BIO_reset(biobuf) + notBefore = libssl_X509_get_notBefore(certificate) + libssl_ASN1_TIME_print(biobuf, notBefore) + with lltype.scoped_alloc(rffi.CCHARP.TO, 100) as buf: + length = libssl_BIO_gets(biobuf, buf, 99) + if length < 0: + raise _ssl_seterror(space, None, length) + w_date = space.wrap(rffi.charpsize2str(buf, length)) + space.setitem(w_retval, space.wrap("notBefore"), w_date) libssl_BIO_reset(biobuf) notAfter = libssl_X509_get_notAfter(certificate) @@ -733,7 +733,6 @@ # Set both the read and write BIO's to non-blocking mode libssl_BIO_set_nbio(libssl_SSL_get_rbio(ss.ssl), 1) libssl_BIO_set_nbio(libssl_SSL_get_wbio(ss.ssl), 1) - libssl_SSL_set_connect_state(ss.ssl) if side == PY_SSL_CLIENT: libssl_SSL_set_connect_state(ss.ssl) 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 @@ -36,6 +36,7 @@ import pypy.module.cpyext.object import pypy.module.cpyext.stringobject import pypy.module.cpyext.tupleobject +import pypy.module.cpyext.ndarrayobject import pypy.module.cpyext.setobject import pypy.module.cpyext.dictobject import pypy.module.cpyext.intobject diff --git a/pypy/module/cpyext/api.py b/pypy/module/cpyext/api.py --- a/pypy/module/cpyext/api.py +++ b/pypy/module/cpyext/api.py @@ -130,11 +130,7 @@ udir.join('pypy_macros.h').write("/* Will be filled later */\n") globals().update(rffi_platform.configure(CConfig_constants)) -def copy_header_files(dstdir): - assert dstdir.check(dir=True) - headers = include_dir.listdir('*.h') + include_dir.listdir('*.inl') - for name in ("pypy_decl.h", "pypy_macros.h"): - headers.append(udir.join(name)) +def _copy_header_files(headers, dstdir): for header in headers: target = dstdir.join(header.basename) try: @@ -145,6 +141,25 @@ target.chmod(0444) # make the file read-only, to make sure that nobody # edits it by mistake +def copy_header_files(dstdir): + # XXX: 20 lines of code to recursively copy a directory, really?? + assert dstdir.check(dir=True) + headers = include_dir.listdir('*.h') + include_dir.listdir('*.inl') + for name in ("pypy_decl.h", "pypy_macros.h"): + headers.append(udir.join(name)) + _copy_header_files(headers, dstdir) + + try: + dstdir.mkdir('numpy') + except py.error.EEXIST: + pass + numpy_dstdir = dstdir / 'numpy' + + numpy_include_dir = include_dir / 'numpy' + numpy_headers = numpy_include_dir.listdir('*.h') + numpy_include_dir.listdir('*.inl') + _copy_header_files(numpy_headers, numpy_dstdir) + + class NotSpecified(object): pass _NOT_SPECIFIED = NotSpecified() @@ -288,9 +303,23 @@ elif isinstance(input_arg, W_Root): arg = input_arg else: - arg = from_ref(space, + try: + arg = from_ref(space, rffi.cast(PyObject, input_arg)) + except TypeError, e: + err = OperationError(space.w_TypeError, + space.wrap( + "could not cast arg to PyObject")) + if not catch_exception: + raise err + state = space.fromcache(State) + state.set_exception(err) + if is_PyObject(restype): + return None + else: + return api_function.error_value else: + # convert to a wrapped object arg = input_arg newargs += (arg, ) try: @@ -309,7 +338,7 @@ return api_function.error_value if not we_are_translated(): got_integer = isinstance(res, (int, long, float)) - assert got_integer == expect_integer + assert got_integer == expect_integer,'got %r not integer' % res if res is None: return None elif isinstance(res, Reference): @@ -386,6 +415,16 @@ 'PyThread_ReInitTLS', 'PyStructSequence_InitType', 'PyStructSequence_New', + + 'PyFunction_Type', 'PyMethod_Type', 'PyRange_Type', 'PyTraceBack_Type', + + 'PyArray_Type', '_PyArray_FILLWBYTE', '_PyArray_ZEROS', '_PyArray_CopyInto', + + 'Py_DebugFlag', 'Py_VerboseFlag', 'Py_InteractiveFlag', 'Py_InspectFlag', + 'Py_OptimizeFlag', 'Py_NoSiteFlag', 'Py_BytesWarningFlag', 'Py_UseClassExceptionsFlag', + 'Py_FrozenFlag', 'Py_TabcheckFlag', 'Py_UnicodeFlag', 'Py_IgnoreEnvironmentFlag', + 'Py_DivisionWarningFlag', 'Py_DontWriteBytecodeFlag', 'Py_NoUserSiteDirectory', + '_Py_QnewFlag', 'Py_Py3kWarningFlag', 'Py_HashRandomizationFlag', '_Py_PackageContext', ] TYPES = {} GLOBALS = { # this needs to include all prebuilt pto, otherwise segfaults occur @@ -975,6 +1014,8 @@ source_dir / "capsule.c", source_dir / "pysignals.c", source_dir / "pythread.c", + source_dir / "ndarrayobject.c", + source_dir / "missing.c", ], separate_module_sources=separate_module_sources, export_symbols=export_symbols_eci, diff --git a/pypy/module/cpyext/include/Python.h b/pypy/module/cpyext/include/Python.h --- a/pypy/module/cpyext/include/Python.h +++ b/pypy/module/cpyext/include/Python.h @@ -126,6 +126,9 @@ #include "pysignals.h" #include "pythread.h" +/* Missing definitions */ +#include "missing.h" + // XXX This shouldn't be included here #include "structmember.h" diff --git a/pypy/module/cpyext/include/boolobject.h b/pypy/module/cpyext/include/boolobject.h --- a/pypy/module/cpyext/include/boolobject.h +++ b/pypy/module/cpyext/include/boolobject.h @@ -7,6 +7,8 @@ extern "C" { #endif +#define PyBoolObject PyIntObject + #define Py_False ((PyObject *) &_Py_ZeroStruct) #define Py_True ((PyObject *) &_Py_TrueStruct) diff --git a/pypy/module/cpyext/include/complexobject.h b/pypy/module/cpyext/include/complexobject.h --- a/pypy/module/cpyext/include/complexobject.h +++ b/pypy/module/cpyext/include/complexobject.h @@ -6,6 +6,9 @@ extern "C" { #endif +/* fake PyComplexObject so that code that doesn't do direct field access works */ +#define PyComplexObject PyObject + typedef struct Py_complex_t { double real; double imag; @@ -13,6 +16,7 @@ /* generated function */ PyAPI_FUNC(void) _PyComplex_AsCComplex(PyObject *, Py_complex *); +PyAPI_FUNC(PyObject *) _PyComplex_FromCComplex(Py_complex *); Py_LOCAL_INLINE(Py_complex) PyComplex_AsCComplex(PyObject *obj) { @@ -21,7 +25,12 @@ return result; } -#define PyComplex_FromCComplex(c) _PyComplex_FromCComplex(&c) +// shmuller 2013/07/30: Make a function, since macro will fail in C++ due to +// const correctness if called with "const Py_complex" +//#define PyComplex_FromCComplex(c) _PyComplex_FromCComplex(&c) +Py_LOCAL_INLINE(PyObject *) PyComplex_FromCComplex(Py_complex c) { + return _PyComplex_FromCComplex(&c); +} #ifdef __cplusplus } diff --git a/pypy/module/cpyext/include/funcobject.h b/pypy/module/cpyext/include/funcobject.h --- a/pypy/module/cpyext/include/funcobject.h +++ b/pypy/module/cpyext/include/funcobject.h @@ -12,6 +12,8 @@ PyObject *func_name; /* The __name__ attribute, a string object */ } PyFunctionObject; +PyAPI_DATA(PyTypeObject) PyFunction_Type; + #define PyFunction_GET_CODE(obj) PyFunction_GetCode((PyObject*)(obj)) #define PyMethod_GET_FUNCTION(obj) PyMethod_Function((PyObject*)(obj)) diff --git a/pypy/module/cpyext/include/missing.h b/pypy/module/cpyext/include/missing.h new file mode 100644 --- /dev/null +++ b/pypy/module/cpyext/include/missing.h @@ -0,0 +1,17 @@ + +/* Definitions from missing header files */ + +#ifndef Py_MISSING_H +#define Py_MISSING_H +#ifdef __cplusplus +extern "C" { +#endif + +PyAPI_DATA(PyTypeObject) PyMethod_Type; +PyAPI_DATA(PyTypeObject) PyRange_Type; +PyAPI_DATA(PyTypeObject) PyTraceBack_Type; + +#ifdef __cplusplus +} +#endif +#endif /* !Py_MISSING_H */ diff --git a/pypy/module/cpyext/include/modsupport.h b/pypy/module/cpyext/include/modsupport.h --- a/pypy/module/cpyext/include/modsupport.h +++ b/pypy/module/cpyext/include/modsupport.h @@ -56,6 +56,7 @@ #define PyMODINIT_FUNC void #endif +PyAPI_DATA(char *) _Py_PackageContext; #ifdef __cplusplus } diff --git a/pypy/module/cpyext/include/numpy/arrayobject.h b/pypy/module/cpyext/include/numpy/arrayobject.h new file mode 100644 --- /dev/null +++ b/pypy/module/cpyext/include/numpy/arrayobject.h @@ -0,0 +1,239 @@ + +/* NDArray object interface - S. H. Muller, 2013/07/26 */ + +#ifndef Py_NDARRAYOBJECT_H +#define Py_NDARRAYOBJECT_H +#ifdef __cplusplus +extern "C" { +#endif + +#include "old_defines.h" + +#define NPY_INLINE +#define NPY_UNUSED(x) x +#define PyArray_MAX(a,b) (((a)>(b))?(a):(b)) +#define PyArray_MIN(a,b) (((a)<(b))?(a):(b)) + +/* fake PyArrayObject so that code that doesn't do direct field access works */ +#define PyArrayObject PyObject +#define PyArray_Descr PyObject + +extern PyTypeObject PyArray_Type; + +typedef unsigned char npy_bool; +typedef unsigned char npy_uint8; +typedef int npy_int; + +#ifndef npy_intp +#define npy_intp long +#endif +#ifndef NPY_INTP_FMT +#define NPY_INTP_FMT "ld" +#endif +#ifndef import_array +#define import_array() +#endif + +#define NPY_MAXDIMS 32 + +typedef struct { + npy_intp *ptr; + int len; +} PyArray_Dims; + +/* data types copied from numpy/ndarraytypes.h + * keep numbers in sync with micronumpy.interp_dtype.DTypeCache + */ +enum NPY_TYPES { NPY_BOOL=0, + NPY_BYTE, NPY_UBYTE, + NPY_SHORT, NPY_USHORT, + NPY_INT, NPY_UINT, + NPY_LONG, NPY_ULONG, + NPY_LONGLONG, NPY_ULONGLONG, + NPY_FLOAT, NPY_DOUBLE, NPY_LONGDOUBLE, + NPY_CFLOAT, NPY_CDOUBLE, NPY_CLONGDOUBLE, + NPY_OBJECT=17, + NPY_STRING, NPY_UNICODE, + NPY_VOID, + /* + * New 1.6 types appended, may be integrated + * into the above in 2.0. + */ + NPY_DATETIME, NPY_TIMEDELTA, NPY_HALF, + + NPY_NTYPES, + NPY_NOTYPE, + NPY_CHAR, /* special flag */ + NPY_USERDEF=256, /* leave room for characters */ + + /* The number of types not including the new 1.6 types */ + NPY_NTYPES_ABI_COMPATIBLE=21 +}; + +#define NPY_INT8 NPY_BYTE +#define NPY_UINT8 NPY_UBYTE +#define NPY_INT16 NPY_SHORT +#define NPY_UINT16 NPY_USHORT +#define NPY_INT32 NPY_INT +#define NPY_UINT32 NPY_UINT +#define NPY_INT64 NPY_LONG +#define NPY_UINT64 NPY_ULONG +#define NPY_FLOAT32 NPY_FLOAT +#define NPY_FLOAT64 NPY_DOUBLE +#define NPY_COMPLEX32 NPY_CFLOAT +#define NPY_COMPLEX64 NPY_CDOUBLE + +#define PyTypeNum_ISBOOL(type) ((type) == NPY_BOOL) +#define PyTypeNum_ISINTEGER(type) (((type) >= NPY_BYTE) && \ + ((type) <= NPY_ULONGLONG)) +#define PyTypeNum_ISFLOAT(type) ((((type) >= NPY_FLOAT) && \ + ((type) <= NPY_LONGDOUBLE)) || \ + ((type) == NPY_HALF)) +#define PyTypeNum_ISCOMPLEX(type) (((type) >= NPY_CFLOAT) && \ + ((type) <= NPY_CLONGDOUBLE)) + +#define PyArray_ISBOOL(arr) (PyTypeNum_ISBOOL(PyArray_TYPE(arr))) +#define PyArray_ISINTEGER(arr) (PyTypeNum_ISINTEGER(PyArray_TYPE(arr))) +#define PyArray_ISFLOAT(arr) (PyTypeNum_ISFLOAT(PyArray_TYPE(arr))) +#define PyArray_ISCOMPLEX(arr) (PyTypeNum_ISCOMPLEX(PyArray_TYPE(arr))) + + +/* flags */ +#define NPY_ARRAY_C_CONTIGUOUS 0x0001 +#define NPY_ARRAY_F_CONTIGUOUS 0x0002 +#define NPY_ARRAY_OWNDATA 0x0004 +#define NPY_ARRAY_FORCECAST 0x0010 +#define NPY_ARRAY_ENSURECOPY 0x0020 +#define NPY_ARRAY_ENSUREARRAY 0x0040 +#define NPY_ARRAY_ELEMENTSTRIDES 0x0080 +#define NPY_ARRAY_ALIGNED 0x0100 +#define NPY_ARRAY_NOTSWAPPED 0x0200 +#define NPY_ARRAY_WRITEABLE 0x0400 +#define NPY_ARRAY_UPDATEIFCOPY 0x1000 + +#define NPY_ARRAY_BEHAVED (NPY_ARRAY_ALIGNED | \ + NPY_ARRAY_WRITEABLE) +#define NPY_ARRAY_BEHAVED_NS (NPY_ARRAY_ALIGNED | \ + NPY_ARRAY_WRITEABLE | \ + NPY_ARRAY_NOTSWAPPED) +#define NPY_ARRAY_CARRAY (NPY_ARRAY_C_CONTIGUOUS | \ + NPY_ARRAY_BEHAVED) +#define NPY_ARRAY_CARRAY_RO (NPY_ARRAY_C_CONTIGUOUS | \ + NPY_ARRAY_ALIGNED) +#define NPY_ARRAY_FARRAY (NPY_ARRAY_F_CONTIGUOUS | \ + NPY_ARRAY_BEHAVED) +#define NPY_ARRAY_FARRAY_RO (NPY_ARRAY_F_CONTIGUOUS | \ + NPY_ARRAY_ALIGNED) +#define NPY_ARRAY_DEFAULT (NPY_ARRAY_CARRAY) +#define NPY_ARRAY_IN_ARRAY (NPY_ARRAY_CARRAY_RO) +#define NPY_ARRAY_OUT_ARRAY (NPY_ARRAY_CARRAY) +#define NPY_ARRAY_INOUT_ARRAY (NPY_ARRAY_CARRAY | \ + NPY_ARRAY_UPDATEIFCOPY) +#define NPY_ARRAY_IN_FARRAY (NPY_ARRAY_FARRAY_RO) +#define NPY_ARRAY_OUT_FARRAY (NPY_ARRAY_FARRAY) +#define NPY_ARRAY_INOUT_FARRAY (NPY_ARRAY_FARRAY | \ + NPY_ARRAY_UPDATEIFCOPY) + +#define NPY_ARRAY_UPDATE_ALL (NPY_ARRAY_C_CONTIGUOUS | \ + NPY_ARRAY_F_CONTIGUOUS | \ + NPY_ARRAY_ALIGNED) + +#define NPY_FARRAY NPY_ARRAY_FARRAY +#define NPY_CARRAY NPY_ARRAY_CARRAY + +#define PyArray_CHKFLAGS(m, flags) (PyArray_FLAGS(m) & (flags)) + +#define PyArray_ISCONTIGUOUS(m) PyArray_CHKFLAGS(m, NPY_ARRAY_C_CONTIGUOUS) +#define PyArray_ISWRITEABLE(m) PyArray_CHKFLAGS(m, NPY_ARRAY_WRITEABLE) +#define PyArray_ISALIGNED(m) PyArray_CHKFLAGS(m, NPY_ARRAY_ALIGNED) + +#define PyArray_IS_C_CONTIGUOUS(m) PyArray_CHKFLAGS(m, NPY_ARRAY_C_CONTIGUOUS) +#define PyArray_IS_F_CONTIGUOUS(m) PyArray_CHKFLAGS(m, NPY_ARRAY_F_CONTIGUOUS) + +#define PyArray_FLAGSWAP(m, flags) (PyArray_CHKFLAGS(m, flags) && \ + PyArray_ISNOTSWAPPED(m)) + +#define PyArray_ISCARRAY(m) PyArray_FLAGSWAP(m, NPY_ARRAY_CARRAY) +#define PyArray_ISCARRAY_RO(m) PyArray_FLAGSWAP(m, NPY_ARRAY_CARRAY_RO) +#define PyArray_ISFARRAY(m) PyArray_FLAGSWAP(m, NPY_ARRAY_FARRAY) +#define PyArray_ISFARRAY_RO(m) PyArray_FLAGSWAP(m, NPY_ARRAY_FARRAY_RO) +#define PyArray_ISBEHAVED(m) PyArray_FLAGSWAP(m, NPY_ARRAY_BEHAVED) +#define PyArray_ISBEHAVED_RO(m) PyArray_FLAGSWAP(m, NPY_ARRAY_ALIGNED) + +#define PyArray_ISONESEGMENT(arr) (1) +#define PyArray_ISNOTSWAPPED(arr) (1) +#define PyArray_ISBYTESWAPPED(arr) (0) + + +/* functions */ +#ifndef PyArray_NDIM + +#define PyArray_Check _PyArray_Check +#define PyArray_CheckExact _PyArray_CheckExact +#define PyArray_FLAGS _PyArray_FLAGS + +#define PyArray_NDIM _PyArray_NDIM +#define PyArray_DIM _PyArray_DIM +#define PyArray_STRIDE _PyArray_STRIDE +#define PyArray_SIZE _PyArray_SIZE +#define PyArray_ITEMSIZE _PyArray_ITEMSIZE +#define PyArray_NBYTES _PyArray_NBYTES +#define PyArray_TYPE _PyArray_TYPE +#define PyArray_DATA _PyArray_DATA + +#define PyArray_Size PyArray_SIZE +#define PyArray_BYTES(arr) ((char *)PyArray_DATA(arr)) + +#define PyArray_FromAny _PyArray_FromAny +#define PyArray_FromObject _PyArray_FromObject +#define PyArray_ContiguousFromObject PyArray_FromObject +#define PyArray_ContiguousFromAny PyArray_FromObject + +#define PyArray_FROMANY(obj, typenum, min, max, requirements) (obj) +#define PyArray_FROM_OTF(obj, typenum, requirements) \ + PyArray_FromObject(obj, typenum, 0, 0) + +#define PyArray_New _PyArray_New +#define PyArray_SimpleNew _PyArray_SimpleNew +#define PyArray_SimpleNewFromData _PyArray_SimpleNewFromData +#define PyArray_SimpleNewFromDataOwning _PyArray_SimpleNewFromDataOwning + +#define PyArray_EMPTY(nd, dims, type_num, fortran) \ + PyArray_SimpleNew(nd, dims, type_num) + +void _PyArray_FILLWBYTE(PyObject* obj, int val); +PyObject* _PyArray_ZEROS(int nd, npy_intp* dims, int type_num, int fortran); +int _PyArray_CopyInto(PyArrayObject* dest, PyArrayObject* src); + +#define PyArray_FILLWBYTE _PyArray_FILLWBYTE +#define PyArray_ZEROS _PyArray_ZEROS +#define PyArray_CopyInto _PyArray_CopyInto + +#define PyArray_Resize(self, newshape, refcheck, fortran) (NULL) + +/* Don't use these in loops! */ + +#define PyArray_GETPTR1(obj, i) ((void *)(PyArray_BYTES(obj) + \ + (i)*PyArray_STRIDE(obj,0))) + +#define PyArray_GETPTR2(obj, i, j) ((void *)(PyArray_BYTES(obj) + \ + (i)*PyArray_STRIDE(obj,0) + \ + (j)*PyArray_STRIDE(obj,1))) + +#define PyArray_GETPTR3(obj, i, j, k) ((void *)(PyArray_BYTES(obj) + \ + (i)*PyArray_STRIDE(obj,0) + \ + (j)*PyArray_STRIDE(obj,1) + \ + (k)*PyArray_STRIDE(obj,2))) + +#define PyArray_GETPTR4(obj, i, j, k, l) ((void *)(PyArray_BYTES(obj) + \ + (i)*PyArray_STRIDE(obj,0) + \ + (j)*PyArray_STRIDE(obj,1) + \ + (k)*PyArray_STRIDE(obj,2) + \ + (l)*PyArray_STRIDE(obj,3))) + +#endif + +#ifdef __cplusplus +} +#endif +#endif /* !Py_NDARRAYOBJECT_H */ diff --git a/pypy/module/cpyext/include/numpy/npy_3kcompat.h b/pypy/module/cpyext/include/numpy/npy_3kcompat.h new file mode 100644 diff --git a/pypy/module/cpyext/include/numpy/old_defines.h b/pypy/module/cpyext/include/numpy/old_defines.h new file mode 100644 --- /dev/null +++ b/pypy/module/cpyext/include/numpy/old_defines.h @@ -0,0 +1,189 @@ +/* This header is deprecated as of NumPy 1.7 */ +#ifndef OLD_DEFINES_H +#define OLD_DEFINES_H + +/* +#if defined(NPY_NO_DEPRECATED_API) && NPY_NO_DEPRECATED_API >= NPY_1_7_API_VERSION +#error The header "old_defines.h" is deprecated as of NumPy 1.7. +#endif +*/ + +#define NDARRAY_VERSION NPY_VERSION + +#define PyArray_MIN_BUFSIZE NPY_MIN_BUFSIZE +#define PyArray_MAX_BUFSIZE NPY_MAX_BUFSIZE +#define PyArray_BUFSIZE NPY_BUFSIZE + +#define PyArray_PRIORITY NPY_PRIORITY +#define PyArray_SUBTYPE_PRIORITY NPY_PRIORITY +#define PyArray_NUM_FLOATTYPE NPY_NUM_FLOATTYPE + +#define NPY_MAX PyArray_MAX +#define NPY_MIN PyArray_MIN + +#define PyArray_TYPES NPY_TYPES +#define PyArray_BOOL NPY_BOOL +#define PyArray_BYTE NPY_BYTE +#define PyArray_UBYTE NPY_UBYTE +#define PyArray_SHORT NPY_SHORT +#define PyArray_USHORT NPY_USHORT +#define PyArray_INT NPY_INT +#define PyArray_UINT NPY_UINT +#define PyArray_LONG NPY_LONG +#define PyArray_ULONG NPY_ULONG +#define PyArray_LONGLONG NPY_LONGLONG +#define PyArray_ULONGLONG NPY_ULONGLONG +#define PyArray_HALF NPY_HALF +#define PyArray_FLOAT NPY_FLOAT +#define PyArray_DOUBLE NPY_DOUBLE +#define PyArray_LONGDOUBLE NPY_LONGDOUBLE +#define PyArray_CFLOAT NPY_CFLOAT +#define PyArray_CDOUBLE NPY_CDOUBLE +#define PyArray_CLONGDOUBLE NPY_CLONGDOUBLE +#define PyArray_OBJECT NPY_OBJECT +#define PyArray_STRING NPY_STRING +#define PyArray_UNICODE NPY_UNICODE +#define PyArray_VOID NPY_VOID +#define PyArray_DATETIME NPY_DATETIME +#define PyArray_TIMEDELTA NPY_TIMEDELTA +#define PyArray_NTYPES NPY_NTYPES +#define PyArray_NOTYPE NPY_NOTYPE +#define PyArray_CHAR NPY_CHAR +#define PyArray_USERDEF NPY_USERDEF +#define PyArray_NUMUSERTYPES NPY_NUMUSERTYPES + +#define PyArray_INTP NPY_INTP +#define PyArray_UINTP NPY_UINTP + +#define PyArray_INT8 NPY_INT8 +#define PyArray_UINT8 NPY_UINT8 +#define PyArray_INT16 NPY_INT16 +#define PyArray_UINT16 NPY_UINT16 +#define PyArray_INT32 NPY_INT32 +#define PyArray_UINT32 NPY_UINT32 + +#ifdef NPY_INT64 +#define PyArray_INT64 NPY_INT64 +#define PyArray_UINT64 NPY_UINT64 +#endif + +#ifdef NPY_INT128 +#define PyArray_INT128 NPY_INT128 +#define PyArray_UINT128 NPY_UINT128 +#endif + +#ifdef NPY_FLOAT16 +#define PyArray_FLOAT16 NPY_FLOAT16 +#define PyArray_COMPLEX32 NPY_COMPLEX32 +#endif + +#ifdef NPY_FLOAT80 +#define PyArray_FLOAT80 NPY_FLOAT80 +#define PyArray_COMPLEX160 NPY_COMPLEX160 +#endif + +#ifdef NPY_FLOAT96 +#define PyArray_FLOAT96 NPY_FLOAT96 +#define PyArray_COMPLEX192 NPY_COMPLEX192 +#endif + +#ifdef NPY_FLOAT128 +#define PyArray_FLOAT128 NPY_FLOAT128 +#define PyArray_COMPLEX256 NPY_COMPLEX256 +#endif + +#define PyArray_FLOAT32 NPY_FLOAT32 +#define PyArray_COMPLEX64 NPY_COMPLEX64 +#define PyArray_FLOAT64 NPY_FLOAT64 +#define PyArray_COMPLEX128 NPY_COMPLEX128 + + +#define PyArray_TYPECHAR NPY_TYPECHAR +#define PyArray_BOOLLTR NPY_BOOLLTR +#define PyArray_BYTELTR NPY_BYTELTR +#define PyArray_UBYTELTR NPY_UBYTELTR +#define PyArray_SHORTLTR NPY_SHORTLTR +#define PyArray_USHORTLTR NPY_USHORTLTR +#define PyArray_INTLTR NPY_INTLTR +#define PyArray_UINTLTR NPY_UINTLTR +#define PyArray_LONGLTR NPY_LONGLTR +#define PyArray_ULONGLTR NPY_ULONGLTR +#define PyArray_LONGLONGLTR NPY_LONGLONGLTR +#define PyArray_ULONGLONGLTR NPY_ULONGLONGLTR +#define PyArray_HALFLTR NPY_HALFLTR +#define PyArray_FLOATLTR NPY_FLOATLTR +#define PyArray_DOUBLELTR NPY_DOUBLELTR +#define PyArray_LONGDOUBLELTR NPY_LONGDOUBLELTR +#define PyArray_CFLOATLTR NPY_CFLOATLTR +#define PyArray_CDOUBLELTR NPY_CDOUBLELTR +#define PyArray_CLONGDOUBLELTR NPY_CLONGDOUBLELTR +#define PyArray_OBJECTLTR NPY_OBJECTLTR +#define PyArray_STRINGLTR NPY_STRINGLTR +#define PyArray_STRINGLTR2 NPY_STRINGLTR2 +#define PyArray_UNICODELTR NPY_UNICODELTR +#define PyArray_VOIDLTR NPY_VOIDLTR +#define PyArray_DATETIMELTR NPY_DATETIMELTR +#define PyArray_TIMEDELTALTR NPY_TIMEDELTALTR +#define PyArray_CHARLTR NPY_CHARLTR +#define PyArray_INTPLTR NPY_INTPLTR +#define PyArray_UINTPLTR NPY_UINTPLTR +#define PyArray_GENBOOLLTR NPY_GENBOOLLTR +#define PyArray_SIGNEDLTR NPY_SIGNEDLTR +#define PyArray_UNSIGNEDLTR NPY_UNSIGNEDLTR +#define PyArray_FLOATINGLTR NPY_FLOATINGLTR +#define PyArray_COMPLEXLTR NPY_COMPLEXLTR + +#define PyArray_QUICKSORT NPY_QUICKSORT +#define PyArray_HEAPSORT NPY_HEAPSORT +#define PyArray_MERGESORT NPY_MERGESORT +#define PyArray_SORTKIND NPY_SORTKIND +#define PyArray_NSORTS NPY_NSORTS + +#define PyArray_NOSCALAR NPY_NOSCALAR +#define PyArray_BOOL_SCALAR NPY_BOOL_SCALAR +#define PyArray_INTPOS_SCALAR NPY_INTPOS_SCALAR +#define PyArray_INTNEG_SCALAR NPY_INTNEG_SCALAR +#define PyArray_FLOAT_SCALAR NPY_FLOAT_SCALAR +#define PyArray_COMPLEX_SCALAR NPY_COMPLEX_SCALAR +#define PyArray_OBJECT_SCALAR NPY_OBJECT_SCALAR +#define PyArray_SCALARKIND NPY_SCALARKIND +#define PyArray_NSCALARKINDS NPY_NSCALARKINDS + +#define PyArray_ANYORDER NPY_ANYORDER +#define PyArray_CORDER NPY_CORDER +#define PyArray_FORTRANORDER NPY_FORTRANORDER +#define PyArray_ORDER NPY_ORDER + +#define PyDescr_ISBOOL PyDataType_ISBOOL +#define PyDescr_ISUNSIGNED PyDataType_ISUNSIGNED +#define PyDescr_ISSIGNED PyDataType_ISSIGNED +#define PyDescr_ISINTEGER PyDataType_ISINTEGER +#define PyDescr_ISFLOAT PyDataType_ISFLOAT +#define PyDescr_ISNUMBER PyDataType_ISNUMBER +#define PyDescr_ISSTRING PyDataType_ISSTRING +#define PyDescr_ISCOMPLEX PyDataType_ISCOMPLEX +#define PyDescr_ISPYTHON PyDataType_ISPYTHON +#define PyDescr_ISFLEXIBLE PyDataType_ISFLEXIBLE +#define PyDescr_ISUSERDEF PyDataType_ISUSERDEF +#define PyDescr_ISEXTENDED PyDataType_ISEXTENDED +#define PyDescr_ISOBJECT PyDataType_ISOBJECT +#define PyDescr_HASFIELDS PyDataType_HASFIELDS + +#define PyArray_LITTLE NPY_LITTLE +#define PyArray_BIG NPY_BIG +#define PyArray_NATIVE NPY_NATIVE +#define PyArray_SWAP NPY_SWAP +#define PyArray_IGNORE NPY_IGNORE + +#define PyArray_NATBYTE NPY_NATBYTE +#define PyArray_OPPBYTE NPY_OPPBYTE + +#define PyArray_MAX_ELSIZE NPY_MAX_ELSIZE + +#define PyArray_USE_PYMEM NPY_USE_PYMEM + +#define PyArray_RemoveLargest PyArray_RemoveSmallest + +#define PyArray_UCS4 npy_ucs4 + +#endif diff --git a/pypy/module/cpyext/include/pythonrun.h b/pypy/module/cpyext/include/pythonrun.h --- a/pypy/module/cpyext/include/pythonrun.h +++ b/pypy/module/cpyext/include/pythonrun.h @@ -6,14 +6,32 @@ extern "C" { #endif - void Py_FatalError(const char *msg); +void Py_FatalError(const char *msg); -/* the -3 option will probably not be implemented */ -#define Py_Py3kWarningFlag 0 +/* taken from Python-2.7.3/Include/pydebug.h */ +PyAPI_DATA(int) Py_DebugFlag; +PyAPI_DATA(int) Py_VerboseFlag; +PyAPI_DATA(int) Py_InteractiveFlag; +PyAPI_DATA(int) Py_InspectFlag; +PyAPI_DATA(int) Py_OptimizeFlag; +PyAPI_DATA(int) Py_NoSiteFlag; +PyAPI_DATA(int) Py_BytesWarningFlag; +PyAPI_DATA(int) Py_UseClassExceptionsFlag; +PyAPI_DATA(int) Py_FrozenFlag; +PyAPI_DATA(int) Py_TabcheckFlag; +PyAPI_DATA(int) Py_UnicodeFlag; +PyAPI_DATA(int) Py_IgnoreEnvironmentFlag; +PyAPI_DATA(int) Py_DivisionWarningFlag; +PyAPI_DATA(int) Py_DontWriteBytecodeFlag; +PyAPI_DATA(int) Py_NoUserSiteDirectory; +/* _XXX Py_QnewFlag should go away in 3.0. It's true iff -Qnew is passed, + * on the command line, and is used in 2.2 by ceval.c to make all "/" divisions + * true divisions (which they will be in 3.0). */ +PyAPI_DATA(int) _Py_QnewFlag; +/* Warn about 3.x issues */ +PyAPI_DATA(int) Py_Py3kWarningFlag; +PyAPI_DATA(int) Py_HashRandomizationFlag; -#define Py_FrozenFlag 0 -#define Py_VerboseFlag 0 -#define Py_DebugFlag 1 typedef struct { int cf_flags; /* bitmask of CO_xxx flags relevant to future */ diff --git a/pypy/module/cpyext/ndarrayobject.py b/pypy/module/cpyext/ndarrayobject.py new file mode 100644 --- /dev/null +++ b/pypy/module/cpyext/ndarrayobject.py @@ -0,0 +1,246 @@ +""" + +Numpy C-API for PyPy - S. H. Muller, 2013/07/26 +""" + +from pypy.interpreter.error import OperationError +from rpython.rtyper.lltypesystem import rffi, lltype +from pypy.module.cpyext.api import cpython_api, Py_ssize_t, CANNOT_FAIL +from pypy.module.cpyext.api import PyObject +from pypy.module.micronumpy.interp_numarray import W_NDimArray, array +from pypy.module.micronumpy.interp_dtype import get_dtype_cache, W_Dtype +from pypy.module.micronumpy.arrayimpl.concrete import ConcreteArray +from pypy.module.micronumpy.arrayimpl.scalar import Scalar +from rpython.rlib.rawstorage import RAW_STORAGE_PTR + +NPY_C_CONTIGUOUS = 0x0001 +NPY_F_CONTIGUOUS = 0x0002 +NPY_OWNDATA = 0x0004 +NPY_FORCECAST = 0x0010 +NPY_ENSURECOPY = 0x0020 +NPY_ENSUREARRAY = 0x0040 +NPY_ELEMENTSTRIDES = 0x0080 +NPY_ALIGNED = 0x0100 +NPY_NOTSWAPPED = 0x0200 +NPY_WRITEABLE = 0x0400 +NPY_UPDATEIFCOPY = 0x1000 + +NPY_BEHAVED = NPY_ALIGNED | NPY_WRITEABLE +NPY_BEHAVED_NS = NPY_ALIGNED | NPY_WRITEABLE | NPY_NOTSWAPPED +NPY_CARRAY = NPY_C_CONTIGUOUS | NPY_BEHAVED +NPY_CARRAY_RO = NPY_C_CONTIGUOUS | NPY_ALIGNED +NPY_FARRAY = NPY_F_CONTIGUOUS | NPY_BEHAVED +NPY_FARRAY_RO = NPY_F_CONTIGUOUS | NPY_ALIGNED +NPY_DEFAULT = NPY_CARRAY +NPY_IN = NPY_CARRAY_RO +NPY_OUT = NPY_CARRAY +NPY_INOUT = NPY_CARRAY | NPY_UPDATEIFCOPY +NPY_IN_FARRAY = NPY_FARRAY_RO +NPY_OUT_FARRAY = NPY_FARRAY +NPY_INOUT_FARRAY = NPY_FARRAY | NPY_UPDATEIFCOPY +NPY_CONTIGUOUS = NPY_C_CONTIGUOUS | NPY_F_CONTIGUOUS +NPY_UPDATE_ALL = NPY_CONTIGUOUS | NPY_ALIGNED + + +# the asserts are needed, otherwise the translation fails + + at cpython_api([PyObject], rffi.INT_real, error=CANNOT_FAIL) +def _PyArray_Check(space, w_obj): + w_obj_type = space.type(w_obj) + w_type = space.gettypeobject(W_NDimArray.typedef) + return (space.is_w(w_obj_type, w_type) or + space.is_true(space.issubtype(w_obj_type, w_type))) + + at cpython_api([PyObject], rffi.INT_real, error=CANNOT_FAIL) +def _PyArray_CheckExact(space, w_obj): + w_obj_type = space.type(w_obj) + w_type = space.gettypeobject(W_NDimArray.typedef) + return space.is_w(w_obj_type, w_type) + + at cpython_api([PyObject], rffi.INT_real, error=CANNOT_FAIL) +def _PyArray_FLAGS(space, w_array): + assert isinstance(w_array, W_NDimArray) + flags = NPY_BEHAVED_NS + if isinstance(w_array.implementation, ConcreteArray): + flags |= NPY_OWNDATA + if len(w_array.get_shape()) < 2: + flags |= NPY_CONTIGUOUS + elif w_array.implementation.order == 'C': + flags |= NPY_C_CONTIGUOUS + else: + flags |= NPY_F_CONTIGUOUS + return flags + + at cpython_api([PyObject], rffi.INT_real, error=CANNOT_FAIL) +def _PyArray_NDIM(space, w_array): + assert isinstance(w_array, W_NDimArray) + return len(w_array.get_shape()) + + at cpython_api([PyObject, Py_ssize_t], Py_ssize_t, error=CANNOT_FAIL) +def _PyArray_DIM(space, w_array, n): + assert isinstance(w_array, W_NDimArray) + return w_array.get_shape()[n] + + at cpython_api([PyObject, Py_ssize_t], Py_ssize_t, error=CANNOT_FAIL) +def _PyArray_STRIDE(space, w_array, n): + assert isinstance(w_array, W_NDimArray) + return w_array.implementation.get_strides()[n] + + at cpython_api([PyObject], Py_ssize_t, error=CANNOT_FAIL) +def _PyArray_SIZE(space, w_array): + assert isinstance(w_array, W_NDimArray) + return w_array.get_size() + + at cpython_api([PyObject], rffi.INT_real, error=CANNOT_FAIL) +def _PyArray_ITEMSIZE(space, w_array): + assert isinstance(w_array, W_NDimArray) + return w_array.get_dtype().get_size() + + at cpython_api([PyObject], Py_ssize_t, error=CANNOT_FAIL) +def _PyArray_NBYTES(space, w_array): + assert isinstance(w_array, W_NDimArray) + return w_array.get_size() * w_array.get_dtype().get_size() + + at cpython_api([PyObject], rffi.INT_real, error=CANNOT_FAIL) +def _PyArray_TYPE(space, w_array): + assert isinstance(w_array, W_NDimArray) + return w_array.get_dtype().num + + + at cpython_api([PyObject], rffi.VOIDP, error=CANNOT_FAIL) +def _PyArray_DATA(space, w_array): + # fails on scalars - see PyArray_FromAny() + assert isinstance(w_array, W_NDimArray) + return rffi.cast(rffi.VOIDP, w_array.implementation.storage) + +PyArray_Descr = PyObject +NULL = lltype.nullptr(rffi.VOIDP.TO) + + at cpython_api([PyObject, PyArray_Descr, Py_ssize_t, Py_ssize_t, Py_ssize_t, rffi.VOIDP], + PyObject) +def _PyArray_FromAny(space, w_obj, w_dtype, min_depth, max_depth, requirements, context): + """ This is the main function used to obtain an array from any nested + sequence, or object that exposes the array interface, op. The + parameters allow specification of the required dtype, the + minimum (min_depth) and maximum (max_depth) number of dimensions + acceptable, and other requirements for the array. + + The dtype argument needs to be a PyArray_Descr structure indicating + the desired data-type (including required byteorder). The dtype + argument may be NULL, indicating that any data-type (and byteorder) + is acceptable. + Unless FORCECAST is present in flags, this call will generate an error + if the data type cannot be safely obtained from the object. If you + want to use NULL for the dtype and ensure the array is notswapped then + use PyArray_CheckFromAny. + + A value of 0 for either of the depth parameters causes the parameter + to be ignored. + + Any of the following array flags can be added (e.g. using |) to get + the requirements argument. If your code can handle general (e.g. + strided, byte-swapped, or unaligned arrays) then requirements + may be 0. Also, if op is not already an array (or does not expose + the array interface), then a new array will be created (and filled + from op using the sequence protocol). The new array will have + NPY_DEFAULT as its flags member. + + The context argument is passed to the __array__ method of op and is + only used if the array is constructed that way. Almost always this + parameter is NULL. + """ + if min_depth !=0 or max_depth != 0: + raise OperationError(space.w_NotImplementedError, space.wrap( + '_PyArray_FromAny called with not-implemented min_dpeth or max_depth argument')) + if requirements not in (0, NPY_DEFAULT): + raise OperationError(space.w_NotImplementedError, space.wrap( + '_PyArray_FromAny called with not-implemented requirements argument')) + w_array = array(space, w_obj, w_dtype=w_dtype, copy=False) + if w_array.is_scalar(): + # since PyArray_DATA() fails on scalars, create a 1D array and set empty + # shape. So the following combination works for *reading* scalars: + # PyObject *arr = PyArray_FromAny(obj); + # int nd = PyArray_NDIM(arr); + # void *data = PyArray_DATA(arr); + impl = w_array.implementation + w_array = W_NDimArray.from_shape(space, [1], impl.dtype) + w_array.implementation.setitem(0, impl.value) + w_array.implementation.shape = [] + return w_array + + at cpython_api([PyObject, Py_ssize_t, Py_ssize_t, Py_ssize_t], PyObject) +def _PyArray_FromObject(space, w_obj, typenum, min_depth, max_depth): + try: + dtype = get_dtype_cache(space).dtypes_by_num[typenum] + except KeyError: + raise OperationError(space.w_ValueError, space.wrap( + '_PyArray_FromObject called with invalid dtype %d' % typenum)) + try: + return _PyArray_FromAny(space, w_obj, dtype, min_depth, max_depth, + 0, NULL); + except OperationError, e: + if e.match(space, space.w_NotImplementedError): + errstr = space.str_w(e.get_w_value(space)) + errstr = '_PyArray_FromObject' + errstr[16:] + raise OperationError(space.w_NotImplementedError, space.wrap( + errstr)) + raise + +def get_shape_and_dtype(space, nd, dims, typenum): + shape = [] + for i in range(nd): + shape.append(rffi.cast(rffi.LONG, dims[i])) + dtype = get_dtype_cache(space).dtypes_by_num[typenum] + return shape, dtype + +def simple_new(space, nd, dims, typenum, + order='C', owning=False, w_subtype=None): + shape, dtype = get_shape_and_dtype(space, nd, dims, typenum) + return W_NDimArray.from_shape(space, shape, dtype) + +def simple_new_from_data(space, nd, dims, typenum, data, + order='C', owning=False, w_subtype=None): + shape, dtype = get_shape_and_dtype(space, nd, dims, typenum) + storage = rffi.cast(RAW_STORAGE_PTR, data) + if nd == 0: + w_val = dtype.itemtype.box_raw_data(storage) + return W_NDimArray(Scalar(dtype, w_val)) + else: + return W_NDimArray.from_shape_and_storage(space, shape, storage, dtype, + order=order, owning=owning, w_subtype=w_subtype) + + + at cpython_api([Py_ssize_t, rffi.LONGP, Py_ssize_t], PyObject) +def _PyArray_SimpleNew(space, nd, dims, typenum): + return simple_new(space, nd, dims, typenum) + + at cpython_api([Py_ssize_t, rffi.LONGP, Py_ssize_t, rffi.VOIDP], PyObject) +def _PyArray_SimpleNewFromData(space, nd, dims, typenum, data): + return simple_new_from_data(space, nd, dims, typenum, data, owning=False) + + at cpython_api([Py_ssize_t, rffi.LONGP, Py_ssize_t, rffi.VOIDP], PyObject) +def _PyArray_SimpleNewFromDataOwning(space, nd, dims, typenum, data): + # Variant to take over ownership of the memory, equivalent to: + # PyObject *arr = PyArray_SimpleNewFromData(nd, dims, typenum, data); + # ((PyArrayObject*)arr)->flags |= NPY_OWNDATA; + return simple_new_from_data(space, nd, dims, typenum, data, owning=True) + + + at cpython_api([rffi.VOIDP, Py_ssize_t, rffi.LONGP, Py_ssize_t, rffi.LONGP, + rffi.VOIDP, Py_ssize_t, Py_ssize_t, PyObject], PyObject) +def _PyArray_New(space, subtype, nd, dims, typenum, strides, data, itemsize, flags, obj): + if strides: + raise OperationError(space.w_NotImplementedError, + space.wrap("strides must be NULL")) + + order = 'C' if flags & NPY_C_CONTIGUOUS else 'F' + owning = True if flags & NPY_OWNDATA else False + w_subtype = None + + if data: + return simple_new_from_data(space, nd, dims, typenum, data, + order=order, owning=owning, w_subtype=w_subtype) + else: + return simple_new(space, nd, dims, typenum, + order=order, owning=owning, w_subtype=w_subtype) + diff --git a/pypy/module/cpyext/number.py b/pypy/module/cpyext/number.py --- a/pypy/module/cpyext/number.py +++ b/pypy/module/cpyext/number.py @@ -1,8 +1,9 @@ from pypy.interpreter.error import OperationError from pypy.module.cpyext.api import cpython_api, CANNOT_FAIL, Py_ssize_t -from pypy.module.cpyext.pyobject import PyObject +from pypy.module.cpyext.pyobject import PyObject, PyObjectP, from_ref, make_ref, Py_DecRef from rpython.rtyper.lltypesystem import rffi, lltype from rpython.tool.sourcetools import func_with_new_name +from pypy.module.cpyext.state import State @cpython_api([PyObject], rffi.INT_real, error=CANNOT_FAIL) def PyIndex_Check(space, w_obj): @@ -56,6 +57,39 @@ """ return space.index(w_obj) + at cpython_api([PyObjectP, PyObjectP], rffi.INT_real, error=CANNOT_FAIL) +def PyNumber_CoerceEx(space, pp1, pp2): + """This function is similar to PyNumber_Coerce(), except that it returns + 1 when the conversion is not possible and when no error is raised. + Reference counts are still not increased in this case.""" + retVal = PyNumber_Coerce(space, pp1, pp2) + if retVal != 0: + return 1 + return 0 + + at cpython_api([PyObjectP, PyObjectP], rffi.INT_real, error=CANNOT_FAIL) +def PyNumber_Coerce(space, pp1, pp2): + """This function takes the addresses of two variables of type PyObject*. If + the objects pointed to by *p1 and *p2 have the same type, increment their + reference count and return 0 (success). If the objects can be converted to a + common numeric type, replace *p1 and *p2 by their converted value (with + 'new' reference counts), and return 0. If no conversion is possible, or if + some other error occurs, return -1 (failure) and don't increment the + reference counts. The call PyNumber_Coerce(&o1, &o2) is equivalent to the + Python statement o1, o2 = coerce(o1, o2).""" + w_obj1 = from_ref(space, pp1[0]) + w_obj2 = from_ref(space, pp2[0]) + try: + w_res = space.coerce(w_obj1, w_obj2) + except (TypeError, OperationError): + state = space.fromcache(State) + state.clear_exception() + return -1 + w_res1, w_res2 = space.unpackiterable(w_res, 2) + pp1[0] = make_ref(space, w_res1) + pp2[0] = make_ref(space, w_res2) + return 0 + def func_rename(newname): return lambda func: func_with_new_name(func, newname) diff --git a/pypy/module/cpyext/src/missing.c b/pypy/module/cpyext/src/missing.c new file mode 100644 --- /dev/null +++ b/pypy/module/cpyext/src/missing.c @@ -0,0 +1,29 @@ +/* Definitions of missing symbols go here */ + +#include "Python.h" + +PyTypeObject PyFunction_Type; + +PyTypeObject PyMethod_Type; +PyTypeObject PyRange_Type; +PyTypeObject PyTraceBack_Type; + +int Py_DebugFlag = 1; +int Py_VerboseFlag = 0; +int Py_InteractiveFlag = 0; +int Py_InspectFlag = 0; +int Py_OptimizeFlag = 0; +int Py_NoSiteFlag = 0; +int Py_BytesWarningFlag = 0; +int Py_UseClassExceptionsFlag = 0; +int Py_FrozenFlag = 0; +int Py_TabcheckFlag = 0; +int Py_UnicodeFlag = 0; +int Py_IgnoreEnvironmentFlag = 0; +int Py_DivisionWarningFlag = 0; +int Py_DontWriteBytecodeFlag = 0; +int Py_NoUserSiteDirectory = 0; +int _Py_QnewFlag = 0; +int Py_Py3kWarningFlag = 0; +int Py_HashRandomizationFlag = 0; + diff --git a/pypy/module/cpyext/src/modsupport.c b/pypy/module/cpyext/src/modsupport.c --- a/pypy/module/cpyext/src/modsupport.c +++ b/pypy/module/cpyext/src/modsupport.c @@ -8,7 +8,9 @@ static PyObject *va_build_value(const char *, va_list, int); -/* Package context -- the full module name for package imports */ +/* Package context -- the full module name for package imports + * Should this be modified in _Py_InitPyPyModule for CPython + * compatibility (see CPython's Py_InitModule4)? */ char *_Py_PackageContext = NULL; /* Py_InitModule4() parameters: diff --git a/pypy/module/cpyext/src/ndarrayobject.c b/pypy/module/cpyext/src/ndarrayobject.c new file mode 100644 --- /dev/null +++ b/pypy/module/cpyext/src/ndarrayobject.c @@ -0,0 +1,27 @@ + +#include "Python.h" +#include "numpy/arrayobject.h" +#include /* memset, memcpy */ + +PyTypeObject PyArray_Type; + +void +_PyArray_FILLWBYTE(PyObject* obj, int val) { + memset(PyArray_DATA(obj), val, PyArray_NBYTES(obj)); +} + +PyObject* +_PyArray_ZEROS(int nd, npy_intp* dims, int type_num, int fortran) +{ + PyObject *arr = PyArray_EMPTY(nd, dims, type_num, fortran); + memset(PyArray_DATA(arr), 0, PyArray_NBYTES(arr)); + return arr; +} + +int +_PyArray_CopyInto(PyArrayObject* dest, PyArrayObject* src) +{ + memcpy(PyArray_DATA(dest), PyArray_DATA(src), PyArray_NBYTES(dest)); + return 0; +} + diff --git a/pypy/module/cpyext/stringobject.py b/pypy/module/cpyext/stringobject.py --- a/pypy/module/cpyext/stringobject.py +++ b/pypy/module/cpyext/stringobject.py @@ -275,7 +275,7 @@ Py_DecRef(space, string[0]) string[0] = make_ref(space, w_str) - at cpython_api([PyObject, rffi.CCHARP, rffi.CCHARP], PyObject) + at cpython_api([PyObject, CONST_STRING, CONST_STRING], PyObject) def PyString_AsEncodedObject(space, w_str, encoding, errors): """Encode a string object using the codec registered for encoding and return the result as Python object. encoding and errors have the same meaning as @@ -294,7 +294,7 @@ w_errors = space.wrap(rffi.charp2str(errors)) return space.call_method(w_str, 'encode', w_encoding, w_errors) - at cpython_api([PyObject, rffi.CCHARP, rffi.CCHARP], PyObject) + at cpython_api([PyObject, CONST_STRING, CONST_STRING], PyObject) def PyString_AsDecodedObject(space, w_str, encoding, errors): """Decode a string object by passing it to the codec registered for encoding and return the result as Python object. encoding and 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 @@ -1528,25 +1528,6 @@ """ raise NotImplementedError - at cpython_api([PyObjectP, PyObjectP], rffi.INT_real, error=-1) -def PyNumber_Coerce(space, p1, p2): - """This function takes the addresses of two variables of type PyObject*. If - the objects pointed to by *p1 and *p2 have the same type, increment their - reference count and return 0 (success). If the objects can be converted to a - common numeric type, replace *p1 and *p2 by their converted value (with - 'new' reference counts), and return 0. If no conversion is possible, or if - some other error occurs, return -1 (failure) and don't increment the - reference counts. The call PyNumber_Coerce(&o1, &o2) is equivalent to the - Python statement o1, o2 = coerce(o1, o2).""" - raise NotImplementedError - - at cpython_api([PyObjectP, PyObjectP], rffi.INT_real, error=-1) -def PyNumber_CoerceEx(space, p1, p2): - """This function is similar to PyNumber_Coerce(), except that it returns - 1 when the conversion is not possible and when no error is raised. - Reference counts are still not increased in this case.""" - raise NotImplementedError - @cpython_api([PyObject, rffi.INT_real], PyObject) def PyNumber_ToBase(space, n, base): """Returns the integer n converted to base as a string with a base diff --git a/pypy/module/cpyext/test/test_api.py b/pypy/module/cpyext/test/test_api.py --- a/pypy/module/cpyext/test/test_api.py +++ b/pypy/module/cpyext/test/test_api.py @@ -46,7 +46,7 @@ raise Exception("DID NOT RAISE") if getattr(space, 'w_' + expected_exc.__name__) is not operror.w_type: raise Exception("Wrong exception") - state.clear_exception() + return state.clear_exception() def setup_method(self, func): freeze_refcnts(self) diff --git a/pypy/module/cpyext/test/test_ndarrayobject.py b/pypy/module/cpyext/test/test_ndarrayobject.py new file mode 100644 --- /dev/null +++ b/pypy/module/cpyext/test/test_ndarrayobject.py @@ -0,0 +1,279 @@ +import py + +from pypy.module.cpyext.test.test_api import BaseApiTest +from pypy.module.cpyext.test.test_cpyext import AppTestCpythonExtensionBase +from rpython.rtyper.lltypesystem import rffi, lltype + +from pypy.module.micronumpy.interp_numarray import W_NDimArray +from pypy.module.micronumpy.interp_dtype import get_dtype_cache + +def scalar(space): + dtype = get_dtype_cache(space).w_float64dtype + return W_NDimArray.new_scalar(space, dtype, space.wrap(10.)) + +def array(space, shape, order='C'): + dtype = get_dtype_cache(space).w_float64dtype + return W_NDimArray.from_shape(space, shape, dtype, order=order) + +def iarray(space, shape, order='C'): + dtype = get_dtype_cache(space).w_int64dtype + return W_NDimArray.from_shape(space, shape, dtype, order=order) + + +NULL = lltype.nullptr(rffi.VOIDP.TO) + +class TestNDArrayObject(BaseApiTest): + + def test_Check(self, space, api): + a = array(space, [10, 5, 3]) + x = space.wrap(10.) + assert api._PyArray_Check(a) + assert api._PyArray_CheckExact(a) + assert not api._PyArray_Check(x) + assert not api._PyArray_CheckExact(x) + + def test_FLAGS(self, space, api): + s = array(space, [10]) + c = array(space, [10, 5, 3], order='C') + f = array(space, [10, 5, 3], order='F') + assert api._PyArray_FLAGS(s) & 0x0001 + assert api._PyArray_FLAGS(s) & 0x0002 + assert api._PyArray_FLAGS(c) & 0x0001 + assert api._PyArray_FLAGS(f) & 0x0002 + assert not api._PyArray_FLAGS(c) & 0x0002 + assert not api._PyArray_FLAGS(f) & 0x0001 + + def test_NDIM(self, space, api): + a = array(space, [10, 5, 3]) + assert api._PyArray_NDIM(a) == 3 + + def test_DIM(self, space, api): + a = array(space, [10, 5, 3]) + assert api._PyArray_DIM(a, 1) == 5 + + def test_STRIDE(self, space, api): + a = array(space, [10, 5, 3], ) + assert api._PyArray_STRIDE(a, 1) == a.implementation.get_strides()[1] + + def test_SIZE(self, space, api): + a = array(space, [10, 5, 3]) + assert api._PyArray_SIZE(a) == 150 + + def test_ITEMSIZE(self, space, api): + a = array(space, [10, 5, 3]) + assert api._PyArray_ITEMSIZE(a) == 8 + + def test_NBYTES(self, space, api): + a = array(space, [10, 5, 3]) + assert api._PyArray_NBYTES(a) == 1200 + + def test_TYPE(self, space, api): + a = array(space, [10, 5, 3]) + assert api._PyArray_TYPE(a) == 12 + + def test_DATA(self, space, api): + a = array(space, [10, 5, 3]) + addr = api._PyArray_DATA(a) + addr2 = rffi.cast(rffi.VOIDP, a.implementation.storage) + assert addr == addr2 + + def test_FromAny_scalar(self, space, api): + a0 = scalar(space) + assert a0.implementation.get_scalar_value().value == 10. + + a = api._PyArray_FromAny(a0, NULL, 0, 0, 0, NULL) + assert api._PyArray_NDIM(a) == 0 + + ptr = rffi.cast(rffi.DOUBLEP, api._PyArray_DATA(a)) + assert ptr[0] == 10. + + def test_FromAny(self, space, api): + a = array(space, [10, 5, 3]) + assert api._PyArray_FromAny(a, NULL, 0, 0, 0, NULL) is a + self.raises(space, api, NotImplementedError, api._PyArray_FromAny, + a, NULL, 0, 3, 0, NULL) + + def test_FromObject(self, space, api): + a = array(space, [10, 5, 3]) + assert api._PyArray_FromObject(a, a.get_dtype().num, 0, 0) is a + exc = self.raises(space, api, NotImplementedError, api._PyArray_FromObject, + a, 11, 0, 3) + assert exc.errorstr(space).find('FromObject') >= 0 + + def test_list_from_fixedptr(self, space, api): + A = lltype.GcArray(lltype.Float) + ptr = lltype.malloc(A, 3) + assert isinstance(ptr, lltype._ptr) + ptr[0] = 10. + ptr[1] = 5. + ptr[2] = 3. + l = list(ptr) + assert l == [10., 5., 3.] + + def test_list_from_openptr(self, space, api): + nd = 3 + a = array(space, [nd]) + ptr = rffi.cast(rffi.DOUBLEP, api._PyArray_DATA(a)) + ptr[0] = 10. + ptr[1] = 5. + ptr[2] = 3. + l = [] + for i in range(nd): + l.append(ptr[i]) + assert l == [10., 5., 3.] + + def test_SimpleNew_scalar(self, space, api): + ptr_s = lltype.nullptr(rffi.LONGP.TO) + a = api._PyArray_SimpleNew(0, ptr_s, 12) + + dtype = get_dtype_cache(space).w_float64dtype + + a.set_scalar_value(dtype.itemtype.box(10.)) + assert a.get_scalar_value().value == 10. + + def test_SimpleNewFromData_scalar(self, space, api): + a = array(space, [1]) + num = api._PyArray_TYPE(a) + ptr_a = api._PyArray_DATA(a) + + x = rffi.cast(rffi.DOUBLEP, ptr_a) + x[0] = float(10.) + + ptr_s = lltype.nullptr(rffi.LONGP.TO) + + res = api._PyArray_SimpleNewFromData(0, ptr_s, num, ptr_a) + assert res.is_scalar() + assert res.get_scalar_value().value == 10. + + def test_SimpleNew(self, space, api): + shape = [10, 5, 3] + nd = len(shape) + + s = iarray(space, [nd]) + ptr_s = rffi.cast(rffi.LONGP, api._PyArray_DATA(s)) + ptr_s[0] = 10 + ptr_s[1] = 5 + ptr_s[2] = 3 + + a = api._PyArray_SimpleNew(nd, ptr_s, 12) + + #assert list(api._PyArray_DIMS(a))[:3] == shape + + ptr_a = api._PyArray_DATA(a) + + x = rffi.cast(rffi.DOUBLEP, ptr_a) + for i in range(150): + x[i] = float(i) + + for i in range(150): + assert x[i] == float(i) + + def test_SimpleNewFromData(self, space, api): + shape = [10, 5, 3] + nd = len(shape) + + s = iarray(space, [nd]) + ptr_s = rffi.cast(rffi.LONGP, api._PyArray_DATA(s)) + ptr_s[0] = 10 + ptr_s[1] = 5 + ptr_s[2] = 3 + + a = array(space, shape) + num = api._PyArray_TYPE(a) + ptr_a = api._PyArray_DATA(a) + + x = rffi.cast(rffi.DOUBLEP, ptr_a) + for i in range(150): + x[i] = float(i) + + res = api._PyArray_SimpleNewFromData(nd, ptr_s, num, ptr_a) + assert api._PyArray_TYPE(res) == num + assert api._PyArray_DATA(res) == ptr_a + for i in range(nd): + assert api._PyArray_DIM(res, i) == shape[i] + ptr_r = rffi.cast(rffi.DOUBLEP, api._PyArray_DATA(res)) + for i in range(150): + assert ptr_r[i] == float(i) + res = api._PyArray_SimpleNewFromDataOwning(nd, ptr_s, num, ptr_a) + x = rffi.cast(rffi.DOUBLEP, ptr_a) + ptr_r = rffi.cast(rffi.DOUBLEP, api._PyArray_DATA(res)) + x[20] = -100. + assert ptr_r[20] == -100. + + def test_SimpleNewFromData_complex(self, space, api): + a = array(space, [2]) + ptr_a = api._PyArray_DATA(a) + + x = rffi.cast(rffi.DOUBLEP, ptr_a) + x[0] = 3. + x[1] = 4. + + ptr_s = lltype.nullptr(rffi.LONGP.TO) + + res = api._PyArray_SimpleNewFromData(0, ptr_s, 15, ptr_a) + assert res.get_scalar_value().real == 3. + assert res.get_scalar_value().imag == 4. + +class AppTestCNumber(AppTestCpythonExtensionBase): + def test_ndarray_object_c(self): + mod = self.import_extension('foo', [ + ("test_simplenew", "METH_NOARGS", + ''' + npy_intp dims[2] ={2, 3}; + PyObject * obj = PyArray_SimpleNew(2, dims, 11); + return obj; + ''' + ), + ("test_fill", "METH_NOARGS", + ''' + npy_intp dims[2] ={2, 3}; + PyObject * obj = PyArray_SimpleNew(2, dims, 1); + PyArray_FILLWBYTE(obj, 42); + return obj; + ''' + ), + ("test_copy", "METH_NOARGS", + ''' + npy_intp dims1[2] ={2, 3}; + npy_intp dims2[2] ={3, 2}; + PyObject * obj1 = PyArray_ZEROS(2, dims1, 11, 0); + PyObject * obj2 = PyArray_ZEROS(2, dims2, 11, 0); + PyArray_FILLWBYTE(obj2, 42); + PyArray_CopyInto(obj2, obj1); + Py_DECREF(obj1); + return obj2; + ''' + ), + ("test_FromAny", "METH_NOARGS", + ''' + npy_intp dims[2] ={2, 3}; + PyObject * obj1 = PyArray_SimpleNew(2, dims, 1); + PyArray_FILLWBYTE(obj1, 42); + PyObject * obj2 = _PyArray_FromAny(obj1, NULL, 0, 0, 0, NULL); + Py_DECREF(obj1); + return obj2; + ''' + ), + ("test_FromObject", "METH_NOARGS", + ''' + npy_intp dims[2] ={2, 3}; + PyObject * obj1 = PyArray_SimpleNew(2, dims, 1); + PyArray_FILLWBYTE(obj1, 42); + PyObject * obj2 = _PyArray_FromObject(obj1, 12, 0, 0); + Py_DECREF(obj1); + return obj2; + ''' + ), + ], prologue='#include ') + arr = mod.test_simplenew() + assert arr.shape == (2, 3) + assert arr.dtype.num == 11 #float32 dtype + arr = mod.test_fill() + assert arr.shape == (2, 3) + assert arr.dtype.num == 1 #int8 dtype + assert (arr == 42).all() + arr = mod.test_copy() + assert (arr == 0).all() + #Make sure these work without errors + arr = mod.test_FromAny() + arr = mod.test_FromObject() diff --git a/pypy/module/cpyext/test/test_number.py b/pypy/module/cpyext/test/test_number.py --- a/pypy/module/cpyext/test/test_number.py +++ b/pypy/module/cpyext/test/test_number.py @@ -1,7 +1,7 @@ -from rpython.rtyper.lltypesystem import rffi, lltype -from pypy.interpreter.error import OperationError +from rpython.rtyper.lltypesystem import lltype from pypy.module.cpyext.test.test_api import BaseApiTest -from pypy.module.cpyext import sequence +from pypy.module.cpyext.pyobject import PyObjectP, from_ref, make_ref, Py_DecRef +from pypy.module.cpyext.test.test_cpyext import AppTestCpythonExtensionBase class TestIterator(BaseApiTest): def test_check(self, space, api): @@ -39,6 +39,46 @@ assert w_l is None api.PyErr_Clear() + def test_coerce(self, space, api): + w_obj1 = space.wrap(123) + w_obj2 = space.wrap(456.789) + pp1 = lltype.malloc(PyObjectP.TO, 1, flavor='raw') + pp1[0] = make_ref(space, w_obj1) + pp2 = lltype.malloc(PyObjectP.TO, 1, flavor='raw') + pp2[0] = make_ref(space, w_obj2) + assert api.PyNumber_Coerce(pp1, pp2) == 0 + assert space.str_w(space.repr(from_ref(space, pp1[0]))) == '123.0' + assert space.str_w(space.repr(from_ref(space, pp2[0]))) == '456.789' + Py_DecRef(space, pp1[0]) + Py_DecRef(space, pp2[0]) + lltype.free(pp1, flavor='raw') + # Yes, decrement twice since we decoupled between w_obj* and pp*[0]. + Py_DecRef(space, w_obj1) + Py_DecRef(space, w_obj2) + lltype.free(pp2, flavor='raw') + + def test_number_coerce_ex(self, space, api): + pl = make_ref(space, space.wrap(123)) + pf = make_ref(space, space.wrap(42.)) + ppl = lltype.malloc(PyObjectP.TO, 1, flavor='raw') + ppf = lltype.malloc(PyObjectP.TO, 1, flavor='raw') + ppl[0] = pl + ppf[0] = pf + + ret = api.PyNumber_CoerceEx(ppl, ppf) + assert ret == 0 + + w_res = from_ref(space, ppl[0]) + + assert api.PyFloat_Check(w_res) + assert space.unwrap(w_res) == 123. + Py_DecRef(space, pl) + Py_DecRef(space, pf) + Py_DecRef(space, ppl[0]) + Py_DecRef(space, ppf[0]) + lltype.free(ppl, flavor='raw') + lltype.free(ppf, flavor='raw') From noreply at buildbot.pypy.org Wed Sep 25 02:19:13 2013 From: noreply at buildbot.pypy.org (pjenvey) Date: Wed, 25 Sep 2013 02:19:13 +0200 (CEST) Subject: [pypy-commit] pypy remove-intlong-smm: rearrange, add an explicit __long__ Message-ID: <20130925001913.557C81C12F0@cobra.cs.uni-duesseldorf.de> Author: Philip Jenvey Branch: remove-intlong-smm Changeset: r67088:7c816e9dadbb Date: 2013-09-24 17:17 -0700 http://bitbucket.org/pypy/pypy/changeset/7c816e9dadbb/ Log: rearrange, add an explicit __long__ 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 @@ -29,6 +29,10 @@ def int(self, space): raise NotImplementedError + def descr_long(self, space): + from pypy.objspace.std.longobject import W_LongObject + return W_LongObject.fromint(space, self.int_w(space)) + def descr_format(self, space, w_format_spec): return newformat.run_formatter(space, w_format_spec, "format_int_or_long", self, @@ -44,9 +48,6 @@ def descr_coerce(self, space, w_other): if not space.isinstance_w(w_other, space.w_int): return space.w_NotImplemented - # XXX: have to call space.int on w_other: 2 - # .__coerce__(True) -> (2, 1): actually cpython doesn't do - # this, so i don't care! return space.newtuple([self, w_other]) def _make_descr_binop(opname): @@ -337,6 +338,40 @@ def descr_getnewargs(self, space): return space.newtuple([wrapint(space, space.int_w(self))]) + def descr_conjugate(self, space): + "Returns self, the complex conjugate of any int." + return space.int(self) + + def descr_bit_length(self, space): + """int.bit_length() -> int + + Number of bits necessary to represent self in binary. + >>> bin(37) + '0b100101' + >>> (37).bit_length() + 6 + """ + val = space.int_w(self) + if val < 0: + val = -val + bits = 0 + while val: + bits += 1 + val >>= 1 + return space.wrap(bits) + + def descr_get_numerator(self, space): + return space.int(self) + + def descr_get_denominator(self, space): + return space.wrap(1) + + def descr_get_real(self, space): + return space.int(self) + + def descr_get_imag(self, space): + return space.wrap(0) + class W_IntObject(W_AbstractIntObject): __slots__ = 'intval' @@ -437,29 +472,6 @@ # ____________________________________________________________ -def descr_conjugate(space, w_int): - "Returns self, the complex conjugate of any int." - return space.int(w_int) - -def descr_bit_length(space, w_int): - """int.bit_length() -> int - - Number of bits necessary to represent self in binary. - >>> bin(37) - '0b100101' - >>> (37).bit_length() - 6 - """ - val = space.int_w(w_int) - if val < 0: - val = -val - bits = 0 - while val: - bits += 1 - val >>= 1 - return space.wrap(bits) - - def wrapint(space, x): if space.config.objspace.std.withprebuiltint: from pypy.objspace.std.intobject import W_IntObject @@ -589,18 +601,6 @@ W_IntObject.__init__(w_obj, value) return w_obj -def descr_get_numerator(space, w_obj): - return space.int(w_obj) - -def descr_get_denominator(space, w_obj): - return space.wrap(1) - -def descr_get_real(space, w_obj): - return space.int(w_obj) - -def descr_get_imag(space, w_obj): - return space.wrap(0) - # ____________________________________________________________ @@ -615,13 +615,14 @@ will be returned instead.''', __new__ = interp2app(descr__new__), - conjugate = interp2app(descr_conjugate), - bit_length = interp2app(descr_bit_length), - numerator = typedef.GetSetProperty(descr_get_numerator), - denominator = typedef.GetSetProperty(descr_get_denominator), - real = typedef.GetSetProperty(descr_get_real), - imag = typedef.GetSetProperty(descr_get_imag), + conjugate = interpindirect2app(W_AbstractIntObject.descr_conjugate), + bit_length = interpindirect2app(W_AbstractIntObject.descr_bit_length), + numerator = typedef.GetSetProperty(W_AbstractIntObject.descr_get_numerator), + denominator = typedef.GetSetProperty(W_AbstractIntObject.descr_get_denominator), + real = typedef.GetSetProperty(W_AbstractIntObject.descr_get_real), + imag = typedef.GetSetProperty(W_AbstractIntObject.descr_get_imag), __int__ = interpindirect2app(W_AbstractIntObject.int), + __long__ = interpindirect2app(W_AbstractIntObject.descr_long), __format__ = interpindirect2app(W_AbstractIntObject.descr_format), __hash__ = interpindirect2app(W_AbstractIntObject.descr_hash), 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 @@ -86,7 +86,7 @@ self.typeorder = { objectobject.W_ObjectObject: [], boolobject.W_BoolObject: [], - intobject.W_IntObject: [], + intobject.W_IntObject: [], # XXX: (And self.typeorder[intobject] below) floatobject.W_FloatObject: [], stringobject.W_StringObject: [], bytearrayobject.W_BytearrayObject: [], From noreply at buildbot.pypy.org Wed Sep 25 10:47:46 2013 From: noreply at buildbot.pypy.org (arigo) Date: Wed, 25 Sep 2013 10:47:46 +0200 (CEST) Subject: [pypy-commit] cffi default: A redo of pull request 19: dynamically determine if the C compiler Message-ID: <20130925084746.42A0C1C3089@cobra.cs.uni-duesseldorf.de> Author: Armin Rigo Branch: Changeset: r1349:447c0de7e517 Date: 2013-09-25 10:47 +0200 http://bitbucket.org/cffi/cffi/changeset/447c0de7e517/ Log: A redo of pull request 19: dynamically determine if the C compiler supports "__thread" or not on this platform. Done slightly more simply in setup.py. diff --git a/c/_cffi_backend.c b/c/_cffi_backend.c --- a/c/_cffi_backend.c +++ b/c/_cffi_backend.c @@ -17,12 +17,6 @@ #include "malloc_closure.h" -/* Define USE__THREAD if gcc on your platform supports "__thread" - global variables. */ -#if !defined(MS_WIN32) && !defined(X86_DARWIN) && !defined(POWERPC_DARWIN) -# define USE__THREAD -#endif - #if PY_MAJOR_VERSION >= 3 # define STR_OR_BYTES "bytes" # define PyText_Type PyUnicode_Type @@ -202,6 +196,8 @@ variable */ #ifndef MS_WIN32 # ifdef USE__THREAD +/* This macro ^^^ is defined by setup.py if it finds that it is + syntactically valid to use "__thread" with this C compiler. */ static __thread int cffi_saved_errno = 0; static void save_errno(void) { cffi_saved_errno = errno; } static void restore_errno(void) { errno = cffi_saved_errno; } diff --git a/c/check__thread.c b/c/check__thread.c new file mode 100644 --- /dev/null +++ b/c/check__thread.c @@ -0,0 +1,1 @@ +__thread int some_threadlocal_variable_42; diff --git a/setup.py b/setup.py --- a/setup.py +++ b/setup.py @@ -41,6 +41,17 @@ # resultlist[:] = res +def ask_supports_thread(): + import distutils.errors + from distutils.ccompiler import new_compiler + compiler = new_compiler(force=1) + try: + compiler.compile(['c/check__thread.c']) + except distutils.errors.CompileError: + print >> sys.stderr, "will not use '__thread' in the C code" + else: + define_macros.append(('USE__THREAD', None)) + def use_pkg_config(): _ask_pkg_config(include_dirs, '--cflags-only-I', '-I', sysroot=True) _ask_pkg_config(extra_compile_args, '--cflags-only-other') @@ -71,6 +82,7 @@ for filename in _filenames) else: use_pkg_config() + ask_supports_thread() if __name__ == '__main__': From noreply at buildbot.pypy.org Wed Sep 25 11:37:54 2013 From: noreply at buildbot.pypy.org (fijal) Date: Wed, 25 Sep 2013 11:37:54 +0200 (CEST) Subject: [pypy-commit] pypy default: merge Message-ID: <20130925093754.90F231C34DF@cobra.cs.uni-duesseldorf.de> Author: Maciej Fijalkowski Branch: Changeset: r67090:a78e2971e1e8 Date: 2013-09-25 11:37 +0200 http://bitbucket.org/pypy/pypy/changeset/a78e2971e1e8/ Log: merge 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 @@ -44,6 +44,13 @@ def test_bool_int(self): assert int(True) is 1 assert int(False) is 0 + # XXX: broken + #assert True.__int__() is 1 + + def test_bool_long(self): + assert long(True) is 1L + assert long(False) is 0L + assert True.__long__() is 1L def test_bool_ops(self): assert True + True == 2 From noreply at buildbot.pypy.org Wed Sep 25 11:37:53 2013 From: noreply at buildbot.pypy.org (fijal) Date: Wed, 25 Sep 2013 11:37:53 +0200 (CEST) Subject: [pypy-commit] pypy default: always pass nothing here Message-ID: <20130925093753.5AF251C3229@cobra.cs.uni-duesseldorf.de> Author: Maciej Fijalkowski Branch: Changeset: r67089:ff3f6477875a Date: 2013-09-25 11:05 +0200 http://bitbucket.org/pypy/pypy/changeset/ff3f6477875a/ Log: always pass nothing here 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 @@ -1682,14 +1682,10 @@ def register_os_tmpnam(self): os_tmpnam = self.llexternal('tmpnam', [rffi.CCHARP], rffi.CCHARP) - def tmpnam_llimpl(name): - buf = rffi.str2charp(name) - try: - return rffi.charp2str(os_tmpnam(buf)) - finally: - lltype.free(buf, flavor='raw') + def tmpnam_llimpl(): + return rffi.charp2str(os_tmpnam(lltype.nullptr(rffi.CCHARP.TO))) - return extdef([str], None, llimpl=tmpnam_llimpl, + return extdef([], None, llimpl=tmpnam_llimpl, export_name="ll_os.ll_os_tmpnam") # --------------------------- os.stat & variants --------------------------- From noreply at buildbot.pypy.org Wed Sep 25 16:17:37 2013 From: noreply at buildbot.pypy.org (rlamy) Date: Wed, 25 Sep 2013 16:17:37 +0200 (CEST) Subject: [pypy-commit] pypy less-stringly-ops: Don't use bare SpaceOperation in rpython.flowspace.generator Message-ID: <20130925141737.4752D1C02AE@cobra.cs.uni-duesseldorf.de> Author: Ronan Lamy Branch: less-stringly-ops Changeset: r67091:b927a28c711a Date: 2013-09-25 02:39 +0100 http://bitbucket.org/pypy/pypy/changeset/b927a28c711a/ Log: Don't use bare SpaceOperation in rpython.flowspace.generator diff --git a/rpython/flowspace/flowcontext.py b/rpython/flowspace/flowcontext.py --- a/rpython/flowspace/flowcontext.py +++ b/rpython/flowspace/flowcontext.py @@ -9,7 +9,7 @@ from rpython.tool.stdlib_opcode import host_bytecode_spec from rpython.flowspace.argument import CallSpec from rpython.flowspace.model import (Constant, Variable, Block, Link, - c_last_exception, SpaceOperation, const, FSException) + c_last_exception, const, FSException) from rpython.flowspace.framestate import (FrameState, recursively_unflatten, recursively_flatten) from rpython.flowspace.specialcase import (rpython_print_item, diff --git a/rpython/flowspace/generator.py b/rpython/flowspace/generator.py --- a/rpython/flowspace/generator.py +++ b/rpython/flowspace/generator.py @@ -1,8 +1,9 @@ """Flow graph building for generators""" from rpython.flowspace.argument import Signature -from rpython.flowspace.model import (Block, Link, SpaceOperation, Variable, - Constant, checkgraph) +from rpython.flowspace.model import (Block, Link, Variable, + Constant, checkgraph, const) +from rpython.flowspace.operation import op from rpython.translator.unsimplify import insert_empty_startblock, split_block from rpython.translator.simplify import eliminate_empty_blocks, simplify_graph from rpython.tool.sourcetools import func_with_new_name @@ -46,19 +47,15 @@ def replace_graph_with_bootstrap(GeneratorIterator, graph): Entry = GeneratorIterator.Entry newblock = Block(graph.startblock.inputargs) - v_generator = Variable('generator') - v_entry = Variable('entry') - newblock.operations.append( - SpaceOperation('simple_call', [Constant(Entry)], v_entry)) + op_entry = op.simple_call(const(Entry)) + v_entry = op_entry.result + newblock.operations.append(op_entry) assert len(graph.startblock.inputargs) == len(Entry.varnames) for v, name in zip(graph.startblock.inputargs, Entry.varnames): - newblock.operations.append( - SpaceOperation('setattr', [v_entry, Constant(name), v], - Variable())) - newblock.operations.append( - SpaceOperation('simple_call', [Constant(GeneratorIterator), v_entry], - v_generator)) - newblock.closeblock(Link([v_generator], graph.returnblock)) + newblock.operations.append(op.setattr(v_entry, Constant(name), v)) + op_generator = op.simple_call(const(GeneratorIterator), v_entry) + newblock.operations.append(op_generator) + newblock.closeblock(Link([op_generator.result], graph.returnblock)) graph.startblock = newblock def attach_next_method(GeneratorIterator, graph): @@ -92,9 +89,9 @@ assert len(varnames) == len(block.inputargs) v_entry1 = Variable('entry') for i, name in enumerate(varnames): - block.operations.insert(i, - SpaceOperation('getattr', [v_entry1, Constant(name)], - block.inputargs[i])) + hlop = op.getattr(v_entry1, const(name)) + hlop.result = block.inputargs[i] + block.operations.insert(i, hlop) block.inputargs = [v_entry1] def tweak_generator_body_graph(Entry, graph): @@ -112,13 +109,10 @@ mappings = [Entry] # stopblock = Block([]) - v0 = Variable() - v1 = Variable() - stopblock.operations = [ - SpaceOperation('simple_call', [Constant(StopIteration)], v0), - SpaceOperation('type', [v0], v1), - ] - stopblock.closeblock(Link([v1, v0], graph.exceptblock)) + op0 = op.simple_call(const(StopIteration)) + op1 = op.type(op0.result) + stopblock.operations = [op0, op1] + stopblock.closeblock(Link([op1.result, op0.result], graph.exceptblock)) # for block in list(graph.iterblocks()): for exit in block.exits: @@ -127,9 +121,9 @@ exit.target = stopblock assert block is not stopblock for index in range(len(block.operations)-1, -1, -1): - op = block.operations[index] - if op.opname == 'yield_': - [v_yielded_value] = op.args + hlop = block.operations[index] + if hlop.opname == 'yield_': + [v_yielded_value] = hlop.args del block.operations[index] newlink = split_block(None, block, index) newblock = newlink.target @@ -143,32 +137,24 @@ # _insert_reads(newblock, varnames) # - v_resume = Variable('resume') - block.operations.append( - SpaceOperation('simple_call', [Constant(Resume)], - v_resume)) + op_resume = op.simple_call(const(Resume)) + block.operations.append(op_resume) + v_resume = op_resume.result for i, name in enumerate(varnames): block.operations.append( - SpaceOperation('setattr', [v_resume, Constant(name), - newlink.args[i]], - Variable())) - v_pair = Variable('pair') - block.operations.append( - SpaceOperation('newtuple', [v_resume, v_yielded_value], - v_pair)) - newlink.args = [v_pair] + op.setattr(v_resume, const(name), newlink.args[i])) + op_pair = op.newtuple(v_resume, v_yielded_value) + block.operations.append(op_pair) + newlink.args = [op_pair.result] newlink.target = graph.returnblock # regular_entry_block = Block([Variable('entry')]) block = regular_entry_block for Resume in mappings: - v_check = Variable() - block.operations.append( - SpaceOperation('simple_call', [Constant(isinstance), - block.inputargs[0], - Constant(Resume)], - v_check)) - block.exitswitch = v_check + op_check = op.simple_call( + const(isinstance), block.inputargs[0], const(Resume)) + block.operations.append(op_check) + block.exitswitch = op_check.result link1 = Link([block.inputargs[0]], Resume.block) link1.exitcase = True nextblock = Block([Variable('entry')]) From noreply at buildbot.pypy.org Wed Sep 25 16:17:42 2013 From: noreply at buildbot.pypy.org (rlamy) Date: Wed, 25 Sep 2013 16:17:42 +0200 (CEST) Subject: [pypy-commit] pypy less-stringly-ops: Add SpaceOperation.replace() Message-ID: <20130925141742.6ADDA1C02AE@cobra.cs.uni-duesseldorf.de> Author: Ronan Lamy Branch: less-stringly-ops Changeset: r67092:aacb3f409865 Date: 2013-09-25 05:31 +0100 http://bitbucket.org/pypy/pypy/changeset/aacb3f409865/ Log: Add SpaceOperation.replace() diff --git a/rpython/flowspace/model.py b/rpython/flowspace/model.py --- a/rpython/flowspace/model.py +++ b/rpython/flowspace/model.py @@ -417,6 +417,11 @@ return "%r = %s(%s)" % (self.result, self.opname, ", ".join(map(repr, self.args))) + def replace(self, mapping): + newargs = [mapping.get(arg, arg) for arg in self.args] + newresult = mapping.get(self.result, self.result) + return type(self)(self.opname, newargs, newresult, self.offset) + class Atom(object): def __init__(self, name): self.__name__ = name # make save_global happy diff --git a/rpython/flowspace/operation.py b/rpython/flowspace/operation.py --- a/rpython/flowspace/operation.py +++ b/rpython/flowspace/operation.py @@ -59,6 +59,14 @@ self.result = Variable() self.offset = -1 + def replace(self, mapping): + newargs = [mapping.get(arg, arg) for arg in self.args] + newresult = mapping.get(self.result, self.result) + newop = type(self)(*newargs) + newop.result = newresult + newop.offset = self.offset + return newop + @classmethod def make_sc(cls): def sc_operator(space, *args_w): diff --git a/rpython/translator/simplify.py b/rpython/translator/simplify.py --- a/rpython/translator/simplify.py +++ b/rpython/translator/simplify.py @@ -265,8 +265,7 @@ def rename(v): return renaming.get(v, v) def rename_op(op): - args = [rename(a) for a in op.args] - op = SpaceOperation(op.opname, args, rename(op.result), op.offset) + op = op.replace(renaming) # special case... if op.opname == 'indirect_call': if isinstance(op.args[0], Constant): From noreply at buildbot.pypy.org Wed Sep 25 17:02:50 2013 From: noreply at buildbot.pypy.org (arigo) Date: Wed, 25 Sep 2013 17:02:50 +0200 (CEST) Subject: [pypy-commit] pypy gcremovetypeptr-32bit: Fix the JIT too. Message-ID: <20130925150250.4773D1C3619@cobra.cs.uni-duesseldorf.de> Author: Armin Rigo Branch: gcremovetypeptr-32bit Changeset: r67095:e2b401122f09 Date: 2013-09-25 16:40 +0200 http://bitbucket.org/pypy/pypy/changeset/e2b401122f09/ Log: Fix the JIT too. 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 @@ -723,7 +723,7 @@ # we use the following algorithm: # - read the typeid from mem(locs[0]), i.e. at offset 0 # - keep the lower 16 bits read there - # - multiply by 4 and use it as an offset in type_info_group + # - multiply by 8 and use it as an offset in type_info_group # - add 16 bytes, to go past the TYPE_INFO structure classptr = y_val # here, we have to go back from 'classptr' to the value expected @@ -733,7 +733,8 @@ type_info_group = llop.gc_get_type_info_group(llmemory.Address) type_info_group = rffi.cast(lltype.Signed, type_info_group) expected_typeid = classptr - sizeof_ti - type_info_group - expected_typeid >>= 2 + assert (expected_typeid & 7) == 0 + expected_typeid >>= 3 if check_imm_arg(expected_typeid): arglocs[1] = imm(expected_typeid) else: 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 @@ -1669,7 +1669,7 @@ # 64-bits) # - keep the lower half of what is read there (i.e. # truncate to an unsigned 'N / 2' bytes value) - # - multiply by 4 (on 32-bits only) and use it as an + # - multiply by 8 (on 32-bits only) and use it as an # offset in type_info_group # - add 16/32 bytes, to go past the TYPE_INFO structure loc = locs[1] @@ -1685,7 +1685,8 @@ type_info_group = rffi.cast(lltype.Signed, type_info_group) expected_typeid = classptr - sizeof_ti - type_info_group if IS_X86_32: - expected_typeid >>= 2 + assert (expected_typeid & 7) == 0 + expected_typeid >>= 3 self.mc.CMP16(mem(locs[0], 0), ImmedLoc(expected_typeid)) elif IS_X86_64: self.mc.CMP32_mi((locs[0].value, 0), expected_typeid) From noreply at buildbot.pypy.org Wed Sep 25 17:02:47 2013 From: noreply at buildbot.pypy.org (arigo) Date: Wed, 25 Sep 2013 17:02:47 +0200 (CEST) Subject: [pypy-commit] pypy gcremovetypeptr-32bit: Fix --gcremovetypeptr on 32-bit. Message-ID: <20130925150247.C168F1C3617@cobra.cs.uni-duesseldorf.de> Author: Armin Rigo Branch: gcremovetypeptr-32bit Changeset: r67093:d82efe79a66a Date: 2013-09-25 16:30 +0200 http://bitbucket.org/pypy/pypy/changeset/d82efe79a66a/ Log: Fix --gcremovetypeptr on 32-bit. From noreply at buildbot.pypy.org Wed Sep 25 17:02:49 2013 From: noreply at buildbot.pypy.org (arigo) Date: Wed, 25 Sep 2013 17:02:49 +0200 (CEST) Subject: [pypy-commit] pypy gcremovetypeptr-32bit: In-progress Message-ID: <20130925150249.209CD1C3618@cobra.cs.uni-duesseldorf.de> Author: Armin Rigo Branch: gcremovetypeptr-32bit Changeset: r67094:993a091dc081 Date: 2013-09-25 16:31 +0200 http://bitbucket.org/pypy/pypy/changeset/993a091dc081/ Log: In-progress diff --git a/rpython/memory/gctypelayout.py b/rpython/memory/gctypelayout.py --- a/rpython/memory/gctypelayout.py +++ b/rpython/memory/gctypelayout.py @@ -311,7 +311,7 @@ fullinfo = lltype.malloc(GCData.VARSIZE_TYPE_INFO, immortal=True, zero=True) info = fullinfo.header - type_id = self.type_info_group.add_member(fullinfo) + type_id = self.type_info_group.add_member(fullinfo, align=8) if self.can_encode_type_shape: encode_type_shape(self, info, TYPE, type_id.index) else: diff --git a/rpython/rtyper/lltypesystem/llgroup.py b/rpython/rtyper/lltypesystem/llgroup.py --- a/rpython/rtyper/lltypesystem/llgroup.py +++ b/rpython/rtyper/lltypesystem/llgroup.py @@ -27,8 +27,9 @@ def __init__(self, name): self.name = name self.members = [] + self.force_aligned = set() - def add_member(self, structptr): + def add_member(self, structptr, align=1): TYPE = lltype.typeOf(structptr) assert isinstance(TYPE.TO, lltype.Struct) assert TYPE.TO._gckind == 'raw' @@ -40,6 +41,9 @@ assert struct._parentstructure() is None index = len(self.members) self.members.append(struct) + assert align in (1, 8) + if align == 8: + self.force_aligned.add(index) _membership[struct] = self return GroupMemberOffset(self, index) 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 @@ -500,6 +500,7 @@ _funccodegen_owner globalcontainer""".split() eci_name = '_compilation_info' + force_aligned = '' def __init__(self, db, T, obj): Node.__init__(self, db) @@ -563,8 +564,9 @@ if name != self.name: lines[0] = '{ ' + lines[0] # extra braces around the 'a' part lines[-1] += ' }' # of the union - lines[0] = '%s = %s' % ( + lines[0] = '%s%s = %s' % ( cdecl(type, name, self.is_thread_local()), + self.force_aligned, lines[0]) lines[-1] += ';' return lines @@ -1027,6 +1029,7 @@ class GroupNode(ContainerNode): nodekind = 'group' count_members = None + force_aligned = ' PYPY_GROUP_ALIGNMENT' def __init__(self, *args): ContainerNode.__init__(self, *args) @@ -1057,13 +1060,18 @@ ctype = ['%s {' % cdecl(self.implementationtypename, '')] for i, member in enumerate(self.obj.members): structtypename = self.db.gettype(typeOf(member)) - ctype.append('\t%s;' % cdecl(structtypename, 'member%d' % i)) + if i in self.obj.force_aligned: + alignment = self.force_aligned + else: + alignment = '' + ctype.append('\t%s%s;' % (cdecl(structtypename, 'member%d' % i), + alignment)) ctype.append('} @') ctype = '\n'.join(ctype) + yield '#include "src/llgroup.h"' yield '%s;' % ( forward_cdecl(ctype, self.name, self.db.standalone, self.is_thread_local())) - yield '#include "src/llgroup.h"' yield 'PYPY_GROUP_CHECK_SIZE(%s)' % (self.name,) for i, member in enumerate(self.obj.members): structnode = self.db.getcontainernode(member) diff --git a/rpython/translator/c/src/llgroup.h b/rpython/translator/c/src/llgroup.h --- a/rpython/translator/c/src/llgroup.h +++ b/rpython/translator/c/src/llgroup.h @@ -6,31 +6,35 @@ #if PYPY_LONG_BIT == 32 /************************************/ /* On 32-bit platforms, a CombinedSymbolic is two USHORTs, and the - lower one stores the offset inside the group, divided by 4. The - limitation is to have at most 256KB of data in the whole group. */ + lower one stores the offset inside the group, divided by 8. The + limitation is to have at most 512KB of data in the whole group. */ + +#define PYPY_GROUP_ALIGNMENT __attribute__((aligned(8))) typedef unsigned short pypy_halfword_t; #define GROUP_MEMBER_OFFSET(grouptype, membername) \ - ((unsigned short)(((long)&((grouptype*)NULL)->membername) / 4)) + ((unsigned short)(((long)&((grouptype*)NULL)->membername) / 8)) #define _OP_GET_GROUP_MEMBER(groupptr, compactoffset) \ - (((char*)groupptr) + ((long)compactoffset)*4) + (((char*)groupptr) + ((long)compactoffset)*8) #define _OP_GET_NEXT_GROUP_MEMBER(groupptr, compactoffset, skipoffset) \ - ((((char*)groupptr) + skipoffset) + ((long)compactoffset)*4) + ((((char*)groupptr) + skipoffset) + ((long)compactoffset)*8) /* A macro to crash at compile-time if sizeof(group) is too large. Uses a hack that I've found on some random forum. Haaaaaaaaaackish. */ #define PYPY_GROUP_CHECK_SIZE(groupname) \ typedef char group_##groupname##_is_too_large[ \ - 2*(sizeof(groupname) <= 65536*4)-1]; + 2*(sizeof(groupname) <= 65536*8)-1]; #else /******************************************************/ /* On 64-bit platforms, a CombinedSymbolic is two UINTs, and the lower one is an 32-bit offset from the start of the group. */ +#define PYPY_GROUP_ALIGNMENT /* nothing */ + typedef unsigned int pypy_halfword_t; #define GROUP_MEMBER_OFFSET(grouptype, membername) \ From noreply at buildbot.pypy.org Wed Sep 25 17:12:56 2013 From: noreply at buildbot.pypy.org (arigo) Date: Wed, 25 Sep 2013 17:12:56 +0200 (CEST) Subject: [pypy-commit] pypy gcremovetypeptr-32bit: Add a warning in the documentation of gcremovetypeptr. Message-ID: <20130925151256.9B8B11C3192@cobra.cs.uni-duesseldorf.de> Author: Armin Rigo Branch: gcremovetypeptr-32bit Changeset: r67096:0561db4deed9 Date: 2013-09-25 15:12 +0000 http://bitbucket.org/pypy/pypy/changeset/0561db4deed9/ Log: Add a warning in the documentation of gcremovetypeptr. diff --git a/rpython/config/translationoption.py b/rpython/config/translationoption.py --- a/rpython/config/translationoption.py +++ b/rpython/config/translationoption.py @@ -76,7 +76,9 @@ "none": [("translation.gcrootfinder", "n/a"), ("translation.gcremovetypeptr", False)], }), - BoolOption("gcremovetypeptr", "Remove the typeptr from every object", + BoolOption("gcremovetypeptr", + "Remove the typeptr from every object. " + + "Note: on 32-bits this only works with gcc for now.", default=IS_64_BITS, cmdline="--gcremovetypeptr"), ChoiceOption("gcrootfinder", "Strategy for finding GC Roots (framework GCs only)", From noreply at buildbot.pypy.org Wed Sep 25 17:53:50 2013 From: noreply at buildbot.pypy.org (arigo) Date: Wed, 25 Sep 2013 17:53:50 +0200 (CEST) Subject: [pypy-commit] pypy default: Issue1599: quadratic time in list.extend(sometuple): test and fix Message-ID: <20130925155350.A5DE51C34DF@cobra.cs.uni-duesseldorf.de> Author: Armin Rigo Branch: Changeset: r67097:69b168abce65 Date: 2013-09-25 17:53 +0200 http://bitbucket.org/pypy/pypy/changeset/69b168abce65/ Log: Issue1599: quadratic time in list.extend(sometuple): test and fix 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 @@ -229,8 +229,13 @@ """ assert newsize >= 0, "negative list length" allocated = len(l.items) - if allocated < newsize or newsize < (allocated >> 1) - 5: - _ll_list_resize_hint_really(l, newsize, False) + if newsize > allocated: + overallocate = True + elif newsize < (allocated >> 1) - 5: + overallocate = False + else: + return + _ll_list_resize_hint_really(l, newsize, overallocate) @signature(types.any(), types.int(), types.bool(), returns=types.none()) def _ll_list_resize_really(l, newsize, overallocate): @@ -273,6 +278,7 @@ with the realloc() to shrink the list. """ cond = newsize < (len(l.items) >> 1) - 5 + # note: overallocate=False should be safe here if jit.isconstant(len(l.items)) and jit.isconstant(newsize): if cond: _ll_list_resize_hint_really(l, newsize, False) diff --git a/rpython/rtyper/rlist.py b/rpython/rtyper/rlist.py --- a/rpython/rtyper/rlist.py +++ b/rpython/rtyper/rlist.py @@ -23,11 +23,11 @@ ADTIList = ADTInterface(ADTIFixedList, { # grow the length if needed, overallocating a bit '_ll_resize_ge': (['self', Signed ], Void), - # shrink the length, keeping it overallocated if useful + # shrink the length; if reallocating, don't keep any overallocation '_ll_resize_le': (['self', Signed ], Void), - # resize to exactly the given size + # resize to exactly the given size; no overallocation '_ll_resize': (['self', Signed ], Void), - # realloc the underlying list + # give a hint about the size; does overallocation if growing '_ll_resize_hint': (['self', Signed ], Void), }) diff --git a/rpython/rtyper/test/test_rlist.py b/rpython/rtyper/test/test_rlist.py --- a/rpython/rtyper/test/test_rlist.py +++ b/rpython/rtyper/test/test_rlist.py @@ -1592,3 +1592,30 @@ assert res == sum(map(ord, 'abcdef')) finally: rlist.ll_getitem_foldable_nonneg = prev + + def test_extend_was_not_overallocating(self): + from rpython.rlib import rgc + from rpython.rlib.objectmodel import resizelist_hint + from rpython.rtyper.lltypesystem import lltype + old_arraycopy = rgc.ll_arraycopy + try: + GLOB = lltype.GcStruct('GLOB', ('seen', lltype.Signed)) + glob = lltype.malloc(GLOB, immortal=True) + glob.seen = 0 + def my_arraycopy(*args): + glob.seen += 1 + return old_arraycopy(*args) + rgc.ll_arraycopy = my_arraycopy + def dummyfn(): + lst = [] + i = 0 + while i < 30: + i += 1 + resizelist_hint(lst, i) + lst.append(i) + return glob.seen + res = self.interpret(dummyfn, []) + finally: + rgc.ll_arraycopy = old_arraycopy + # + assert 2 <= res <= 10 From noreply at buildbot.pypy.org Wed Sep 25 18:12:20 2013 From: noreply at buildbot.pypy.org (arigo) Date: Wed, 25 Sep 2013 18:12:20 +0200 (CEST) Subject: [pypy-commit] pypy gcremovetypeptr-32bit: Hack to enable gcremovetypeptr always Message-ID: <20130925161220.562F91C0204@cobra.cs.uni-duesseldorf.de> Author: Armin Rigo Branch: gcremovetypeptr-32bit Changeset: r67098:1ede42f90b53 Date: 2013-09-25 16:11 +0000 http://bitbucket.org/pypy/pypy/changeset/1ede42f90b53/ Log: Hack to enable gcremovetypeptr always diff --git a/rpython/config/translationoption.py b/rpython/config/translationoption.py --- a/rpython/config/translationoption.py +++ b/rpython/config/translationoption.py @@ -79,7 +79,8 @@ BoolOption("gcremovetypeptr", "Remove the typeptr from every object. " + "Note: on 32-bits this only works with gcc for now.", - default=IS_64_BITS, cmdline="--gcremovetypeptr"), + default=True, #IS_64_BITS, --- XXX temporary! + cmdline="--gcremovetypeptr"), ChoiceOption("gcrootfinder", "Strategy for finding GC Roots (framework GCs only)", ["n/a", "shadowstack", "asmgcc"], From noreply at buildbot.pypy.org Wed Sep 25 19:12:27 2013 From: noreply at buildbot.pypy.org (arigo) Date: Wed, 25 Sep 2013 19:12:27 +0200 (CEST) Subject: [pypy-commit] buildbot default: Baaaah. I didn't find out how to use Mercurial() for auxiliary repos Message-ID: <20130925171227.F31041C0204@cobra.cs.uni-duesseldorf.de> Author: Armin Rigo Branch: Changeset: r864:3c3490a01a5d Date: 2013-09-25 19:11 +0200 http://bitbucket.org/pypy/buildbot/changeset/3c3490a01a5d/ Log: Baaaah. I didn't find out how to use Mercurial() for auxiliary repos where we *don't* want to update to the branch specified by the user. diff --git a/bot2/pypybuildbot/builds.py b/bot2/pypybuildbot/builds.py --- a/bot2/pypybuildbot/builds.py +++ b/bot2/pypybuildbot/builds.py @@ -243,8 +243,52 @@ self.finished(SUCCESS) +def update_hg_old_method(platform, factory, repourl, workdir): + # baaaaaah. Seems that the Mercurial class doesn't support + # updating to a different branch than the one specified by + # the user (like "default"). This is nonsense if we need + # an auxiliary check-out :-( At least I didn't find how. + if platform == 'win32': + command = "if not exist .hg rmdir /q /s ." + else: + command = "if [ ! -d .hg ]; then rm -fr * .[a-z]*; fi" + factory.addStep(ShellCmd(description="rmdir?", + command=command, + workdir=workdir, + haltOnFailure=False)) + # + if platform == "win32": + command = "if not exist .hg %s" + else: + command = "if [ ! -d .hg ]; then %s; fi" + command = command % ("hg clone -U " + repourl + " .") + factory.addStep(ShellCmd(description="hg clone", + command=command, + workdir=workdir, + timeout=3600, + haltOnFailure=True)) + # + factory.addStep( + ShellCmd(description="hg purge", + command="hg --config extensions.purge= purge --all", + workdir=workdir, + haltOnFailure=True)) + # + factory.addStep(ShellCmd(description="hg pull", + command="hg pull", + workdir=workdir)) + # + # here, update without caring about branches + factory.addStep(ShellCmd(description="hg update", + command=WithProperties("hg update --clean %(revision)s"), + workdir=workdir)) + def update_hg(platform, factory, repourl, workdir, use_branch, force_branch=None): + if not use_branch: + assert force_branch is None + update_hg_old_method(platform, factory, repourl, workdir) + return factory.addStep( Mercurial( repourl=repourl, From noreply at buildbot.pypy.org Wed Sep 25 19:50:30 2013 From: noreply at buildbot.pypy.org (fijal) Date: Wed, 25 Sep 2013 19:50:30 +0200 (CEST) Subject: [pypy-commit] pypy default: revert this checkin Message-ID: <20130925175030.49B341C35F8@cobra.cs.uni-duesseldorf.de> Author: Maciej Fijalkowski Branch: Changeset: r67100:28ab64adf695 Date: 2013-09-25 17:04 +0200 http://bitbucket.org/pypy/pypy/changeset/28ab64adf695/ Log: revert this checkin diff --git a/rpython/rlib/listsort.py b/rpython/rlib/listsort.py --- a/rpython/rlib/listsort.py +++ b/rpython/rlib/listsort.py @@ -8,7 +8,7 @@ ## Adapted from CPython, original code and algorithms by Tim Peters def make_timsort_class(getitem=None, setitem=None, length=None, - getitem_slice=None, lt=None, base_class=object): + getitem_slice=None, lt=None): if getitem is None: def getitem(list, item): @@ -30,7 +30,7 @@ def lt(a, b): return a < b - class TimSort(base_class): + class TimSort(object): """TimSort(list).sort() Sorts the list in-place, using the overridable method lt() for comparison. From noreply at buildbot.pypy.org Wed Sep 25 19:50:31 2013 From: noreply at buildbot.pypy.org (fijal) Date: Wed, 25 Sep 2013 19:50:31 +0200 (CEST) Subject: [pypy-commit] pypy default: merge Message-ID: <20130925175031.6B1E71C3615@cobra.cs.uni-duesseldorf.de> Author: Maciej Fijalkowski Branch: Changeset: r67101:a1fcfcbca813 Date: 2013-09-25 19:49 +0200 http://bitbucket.org/pypy/pypy/changeset/a1fcfcbca813/ Log: merge 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 @@ -229,8 +229,13 @@ """ assert newsize >= 0, "negative list length" allocated = len(l.items) - if allocated < newsize or newsize < (allocated >> 1) - 5: - _ll_list_resize_hint_really(l, newsize, False) + if newsize > allocated: + overallocate = True + elif newsize < (allocated >> 1) - 5: + overallocate = False + else: + return + _ll_list_resize_hint_really(l, newsize, overallocate) @signature(types.any(), types.int(), types.bool(), returns=types.none()) def _ll_list_resize_really(l, newsize, overallocate): @@ -273,6 +278,7 @@ with the realloc() to shrink the list. """ cond = newsize < (len(l.items) >> 1) - 5 + # note: overallocate=False should be safe here if jit.isconstant(len(l.items)) and jit.isconstant(newsize): if cond: _ll_list_resize_hint_really(l, newsize, False) diff --git a/rpython/rtyper/rlist.py b/rpython/rtyper/rlist.py --- a/rpython/rtyper/rlist.py +++ b/rpython/rtyper/rlist.py @@ -23,11 +23,11 @@ ADTIList = ADTInterface(ADTIFixedList, { # grow the length if needed, overallocating a bit '_ll_resize_ge': (['self', Signed ], Void), - # shrink the length, keeping it overallocated if useful + # shrink the length; if reallocating, don't keep any overallocation '_ll_resize_le': (['self', Signed ], Void), - # resize to exactly the given size + # resize to exactly the given size; no overallocation '_ll_resize': (['self', Signed ], Void), - # realloc the underlying list + # give a hint about the size; does overallocation if growing '_ll_resize_hint': (['self', Signed ], Void), }) diff --git a/rpython/rtyper/test/test_rlist.py b/rpython/rtyper/test/test_rlist.py --- a/rpython/rtyper/test/test_rlist.py +++ b/rpython/rtyper/test/test_rlist.py @@ -1592,3 +1592,30 @@ assert res == sum(map(ord, 'abcdef')) finally: rlist.ll_getitem_foldable_nonneg = prev + + def test_extend_was_not_overallocating(self): + from rpython.rlib import rgc + from rpython.rlib.objectmodel import resizelist_hint + from rpython.rtyper.lltypesystem import lltype + old_arraycopy = rgc.ll_arraycopy + try: + GLOB = lltype.GcStruct('GLOB', ('seen', lltype.Signed)) + glob = lltype.malloc(GLOB, immortal=True) + glob.seen = 0 + def my_arraycopy(*args): + glob.seen += 1 + return old_arraycopy(*args) + rgc.ll_arraycopy = my_arraycopy + def dummyfn(): + lst = [] + i = 0 + while i < 30: + i += 1 + resizelist_hint(lst, i) + lst.append(i) + return glob.seen + res = self.interpret(dummyfn, []) + finally: + rgc.ll_arraycopy = old_arraycopy + # + assert 2 <= res <= 10 From noreply at buildbot.pypy.org Wed Sep 25 19:50:29 2013 From: noreply at buildbot.pypy.org (fijal) Date: Wed, 25 Sep 2013 19:50:29 +0200 (CEST) Subject: [pypy-commit] pypy default: Make it possible to have multiple subclasses of TimSort mixed together, if Message-ID: <20130925175029.0B1A41C35F3@cobra.cs.uni-duesseldorf.de> Author: Maciej Fijalkowski Branch: Changeset: r67099:4daed7bb7a01 Date: 2013-09-25 16:03 +0200 http://bitbucket.org/pypy/pypy/changeset/4daed7bb7a01/ Log: Make it possible to have multiple subclasses of TimSort mixed together, if necessary diff --git a/rpython/rlib/listsort.py b/rpython/rlib/listsort.py --- a/rpython/rlib/listsort.py +++ b/rpython/rlib/listsort.py @@ -8,7 +8,7 @@ ## Adapted from CPython, original code and algorithms by Tim Peters def make_timsort_class(getitem=None, setitem=None, length=None, - getitem_slice=None, lt=None): + getitem_slice=None, lt=None, base_class=object): if getitem is None: def getitem(list, item): @@ -30,7 +30,7 @@ def lt(a, b): return a < b - class TimSort(object): + class TimSort(base_class): """TimSort(list).sort() Sorts the list in-place, using the overridable method lt() for comparison. From noreply at buildbot.pypy.org Wed Sep 25 20:07:30 2013 From: noreply at buildbot.pypy.org (fijal) Date: Wed, 25 Sep 2013 20:07:30 +0200 (CEST) Subject: [pypy-commit] pypy resume-refactor: progress Message-ID: <20130925180730.8ACEA1C35F8@cobra.cs.uni-duesseldorf.de> Author: Maciej Fijalkowski Branch: resume-refactor Changeset: r67102:74607bbebebf Date: 2013-09-25 20:06 +0200 http://bitbucket.org/pypy/pypy/changeset/74607bbebebf/ Log: 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 @@ -4,7 +4,7 @@ from rpython.jit.metainterp.history import (INT, REF, FLOAT, JitCellToken, ConstInt, BoxInt, AbstractFailDescr) from rpython.jit.metainterp.resoperation import ResOperation, rop -from rpython.jit.metainterp.resume2 import rebuild_locs_from_resumedata +#from rpython.jit.metainterp.resume2 import rebuild_locs_from_resumedata from rpython.rlib import rgc from rpython.rlib.debug import (debug_start, debug_stop, have_debug_prints, debug_print) 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 @@ -469,15 +469,14 @@ 'READ_TIMESTAMP/0', 'MARK_OPAQUE_PTR/1b', '_RESUME_FIRST', + # resume-only operations that never make it to the real assembler 'ENTER_FRAME/1d', 'LEAVE_FRAME/0', 'RESUME_PUT/3', 'RESUME_NEW/0d', 'RESUME_SETFIELD_GC/2d', 'BACKEND_ATTACH/2', - # same as resume_put, but the first arg is backend-dependent, - # instead of a box - '_RESUME_LAST', + '_RESUME_LAST', # ----- end of resume only operations ------ '_NOSIDEEFFECT_LAST', # ----- end of no_side_effect operations ----- 'SETARRAYITEM_GC/3d', diff --git a/rpython/jit/metainterp/resume2.py b/rpython/jit/metainterp/resume2.py --- a/rpython/jit/metainterp/resume2.py +++ b/rpython/jit/metainterp/resume2.py @@ -14,6 +14,10 @@ def rebuild(self, faildescr): self._rebuild_until(faildescr.rd_resume_bytecode, faildescr.rd_bytecode_position) + self.finish() + + def finish(self): + pass def _rebuild_until(self, rb, position): if rb.parent is not None: @@ -37,6 +41,8 @@ elif op.getopnum() == rop.RESUME_SETFIELD_GC: self.resume_setfield_gc(op.getarg(0), op.getarg(1), op.getdescr()) + elif op.getopnum() == rop.BACKEND_ATTACH: + self.resume_backend_attach(op.getarg(0), op.getarg(1).getint()) elif not op.is_resume(): pos += 1 continue @@ -44,12 +50,11 @@ xxx pos += 1 - def resume_put(self, jitframe_index, depth, frontend_position): - XXX + def resume_put(self, box, depth, frontend_position): jitcode = self.metainterp.framestack[-1].jitcode frame = self.metainterp.framestack[- depth - 1] if frontend_position < jitcode.num_regs_i(): - self.write_int(frame, frontend_position, jitframe_index) + self.put_box_int(frame, frontend_position, box) elif frontend_position < (jitcode.num_regs_r() + jitcode.num_regs_i()): xxx else: @@ -63,6 +68,10 @@ def __init__(self, metainterp, deadframe): self.metainterp = metainterp self.deadframe = deadframe + self.backend_values = {} + + def resume_backend_attach(self, box, position): + self.backend_values[box] = position def enter_frame(self, pc, jitcode): if pc != -1: @@ -72,49 +81,18 @@ def leave_frame(self): self.metainterp.popframe() - def write_int(self, frame, pos, jitframe_index): + def put_box_int(self, frame, position, box): + frame.registers_i[position] = box + + def finish(self): cpu = self.metainterp.cpu - value = cpu.get_int_value(self.deadframe, jitframe_index) - frame.registers_i[pos] = BoxInt(value) - -class ReconstructingResumeReader(AbstractResumeReader): - def __init__(self): - self.framestack = [] - - def enter_frame(self, pc, jitcode): - self.framestack.append([-1] * jitcode.num_regs()) - - def put(self, jitframe_index, depth, frontend_position): - self.framestack[- depth - 1][frontend_position] = jitframe_index - - def leave_frame(self): - self.framestack.pop() - -class SimpleResumeReader(AbstractResumeReader): - def __init__(self): - self.framestack = [] - - def enter_frame(self, pc, jitcode): - self.framestack.append(jitcode.num_regs()) - - def put(self, *args): - pass - - def leave_frame(self): - self.framestack.pop() + for box, position in self.backend_values.iteritems(): + if box.type == 'i': + intval = cpu.get_int_value(self.deadframe, position) + assert isinstance(box, BoxInt) + box.value = intval + else: + xxx def rebuild_from_resumedata(metainterp, deadframe, faildescr): BoxResumeReader(metainterp, deadframe).rebuild(faildescr) - -def rebuild_locs_from_resumedata(faildescr): - reader = ReconstructingResumeReader() - reader.rebuild(faildescr) - size = 0 - for frame in reader.framestack: - size += len(frame) - res = [-1] * size - i = 0 - for frame in reader.framestack: - res[i : i + len(frame)] = frame - i += len(frame) - return res diff --git a/rpython/jit/metainterp/test/test_resume2.py b/rpython/jit/metainterp/test/test_resume2.py --- a/rpython/jit/metainterp/test/test_resume2.py +++ b/rpython/jit/metainterp/test/test_resume2.py @@ -3,7 +3,7 @@ from rpython.jit.codewriter.jitcode import JitCode from rpython.jit.metainterp.history import AbstractDescr from rpython.jit.metainterp.resume2 import rebuild_from_resumedata,\ - rebuild_locs_from_resumedata, ResumeBytecode + ResumeBytecode class Descr(AbstractDescr): @@ -40,14 +40,15 @@ jitcode = JitCode("jitcode") jitcode.setup(num_regs_i=13) resume_loop = parse(""" - [] + [i0] enter_frame(-1, descr=jitcode1) - backend_put(10, 0, 1) + resume_put(i0, 0, 1) + backend_attach(i0, 10) leave_frame() """, namespace={'jitcode1': jitcode}) descr = Descr() descr.rd_resume_bytecode = ResumeBytecode(resume_loop.operations) - descr.rd_bytecode_position = 2 + descr.rd_bytecode_position = 3 metainterp = MockMetaInterp() metainterp.cpu = MockCPU() rebuild_from_resumedata(metainterp, "myframe", descr) @@ -61,21 +62,25 @@ jitcode2 = JitCode("jitcode2") jitcode2.setup(num_regs_i=9) resume_loop = parse(""" - [] + [i0, i1, i2, i3] enter_frame(-1, descr=jitcode1) - backend_put(11, 0, 2) + resume_put(i0, 0, 2) + backend_attach(i0, 11) enter_frame(12, descr=jitcode2) - backend_put(12, 0, 3) - backend_put(8, 1, 4) + resume_put(i1, 0, 3) + resume_put(i2, 1, 4) + backend_attach(i1, 12) + backend_attach(i2, 8) leave_frame() - backend_put(10, 0, 1) + backend_attach(i3, 10) + resume_put(i3, 0, 1) leave_frame() """, namespace={'jitcode1': jitcode1, 'jitcode2': jitcode2}) metainterp = MockMetaInterp() metainterp.cpu = MockCPU() descr = Descr() descr.rd_resume_bytecode = ResumeBytecode(resume_loop.operations) - descr.rd_bytecode_position = 5 + descr.rd_bytecode_position = 8 rebuild_from_resumedata(metainterp, "myframe", descr) assert len(metainterp.framestack) == 2 f = metainterp.framestack[-1] @@ -86,7 +91,7 @@ assert f2.registers_i[4].getint() == 8 + 3 assert f2.registers_i[2].getint() == 11 + 3 - descr.rd_bytecode_position = 7 + descr.rd_bytecode_position = 11 metainterp.framestack = [] rebuild_from_resumedata(metainterp, "myframe", descr) assert len(metainterp.framestack) == 1 @@ -100,21 +105,24 @@ jitcode1 = JitCode("jitcode") jitcode1.setup(num_regs_i=13) base = parse(""" - [] + [i0, i1] enter_frame(-1, descr=jitcode1) - backend_put(42, 0, 0) + resume_put(i0, 0, 0) + backend_attach(i0, 42) # here is the split caused by a guard - backend_put(1, 0, 1) + resume_put(i1, 0, 1) + backend_attach(i1, 1) """, namespace={'jitcode1': jitcode1}) bridge = parse(""" - [] - backend_put(2, 0, 1) + [i2] + resume_put(i2, 0, 1) + backend_attach(i2, 2) """) descr = Descr() - descr.rd_bytecode_position = 1 + descr.rd_bytecode_position = 2 parent = ResumeBytecode(base.operations) b = ResumeBytecode(bridge.operations, parent=parent, - parent_position=2) + parent_position=3) descr.rd_resume_bytecode = b metainterp = MockMetaInterp() metainterp.cpu = MockCPU() @@ -125,17 +133,19 @@ assert f.registers_i[1].getint() == 2 + 3 def test_new(self): + jitcode1 = JitCode("jitcode") + jitcode1.setup(num_regs_i=1) base = parse(""" [] enter_frame(-1, descr=jitcode) i0 = new(descr=structdescr) - XXX - resume_setfield(i0, 13 + resume_setfield(i0, 13, descr=fielddescr) backend_put(12, leave_frame() - """) + """, namespace={'jitcode':jitcode}) def test_reconstructing_resume_reader(self): + XXX jitcode1 = JitCode("jitcode") jitcode1.setup(num_regs_i=3, num_regs_f=0, num_regs_r=0) jitcode2 = JitCode("jitcode2") From noreply at buildbot.pypy.org Wed Sep 25 20:29:02 2013 From: noreply at buildbot.pypy.org (alex_gaynor) Date: Wed, 25 Sep 2013 20:29:02 +0200 (CEST) Subject: [pypy-commit] pypy resume-refactor: Converted another test to the new format Message-ID: <20130925182902.E715D1C3192@cobra.cs.uni-duesseldorf.de> Author: Alex Gaynor Branch: resume-refactor Changeset: r67103:af6dd12d022e Date: 2013-09-25 11:28 -0700 http://bitbucket.org/pypy/pypy/changeset/af6dd12d022e/ Log: Converted another test to the new format 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 @@ -1,11 +1,20 @@ -import py, sys, random, os, struct, operator +import gc +import operator +import os +import random +import struct +import sys +import weakref + +import py + from rpython.jit.metainterp.history import (AbstractFailDescr, AbstractDescr, BasicFailDescr, BasicFinalDescr, BoxInt, Box, BoxPtr, JitCellToken, TargetToken, - ConstInt, ConstPtr, + ConstInt, BoxFloat, ConstFloat) from rpython.jit.metainterp.resoperation import ResOperation, rop from rpython.jit.metainterp.typesystem import deref @@ -184,7 +193,6 @@ assert res == 10 def test_backends_dont_keep_loops_alive(self): - import weakref, gc self.cpu.dont_keepalive_stuff = True i0 = BoxInt() i1 = BoxInt() @@ -3718,19 +3726,23 @@ targettoken1 = TargetToken() targettoken2 = TargetToken() faildescr = BasicFailDescr(2) + jitcode = JitCode("name") + jitcode.setup(num_regs_i=1, num_regs_r=0, num_regs_f=0) operations = [ + ResOperation(rop.ENTER_FRAME, [ConstInt(-1)], None, descr=jitcode), ResOperation(rop.LABEL, [i0], None, descr=targettoken1), ResOperation(rop.INT_ADD, [i0, ConstInt(1)], i1), ResOperation(rop.INT_LE, [i1, ConstInt(9)], i2), + ResOperation(rop.RESUME_PUT, [i1, ConstInt(0), ConstInt(0)], None), ResOperation(rop.GUARD_TRUE, [i2], None, descr=faildescr), ResOperation(rop.LABEL, [i1], None, descr=targettoken2), + ResOperation(rop.RESUME_PUT, [i1, ConstInt(0), ConstInt(0)], None), ResOperation(rop.INT_GE, [i1, ConstInt(0)], i3), ResOperation(rop.GUARD_TRUE, [i3], None, descr=BasicFailDescr(3)), + ResOperation(rop.LEAVE_FRAME, [], None), ResOperation(rop.JUMP, [i1], None, descr=targettoken1), - ] + ] inputargs = [i0] - operations[3].setfailargs([i1]) - operations[6].setfailargs([i1]) self.cpu.compile_loop(None, inputargs, operations, looptoken) deadframe = self.cpu.execute_token(looptoken, 2) From noreply at buildbot.pypy.org Wed Sep 25 20:31:20 2013 From: noreply at buildbot.pypy.org (alex_gaynor) Date: Wed, 25 Sep 2013 20:31:20 +0200 (CEST) Subject: [pypy-commit] pypy resume-refactor: Backed out changeset af6dd12d022e Message-ID: <20130925183120.26E321C3192@cobra.cs.uni-duesseldorf.de> Author: Alex Gaynor Branch: resume-refactor Changeset: r67104:e298c033de1e Date: 2013-09-25 11:30 -0700 http://bitbucket.org/pypy/pypy/changeset/e298c033de1e/ Log: Backed out changeset af6dd12d022e 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 @@ -1,20 +1,11 @@ -import gc -import operator -import os -import random -import struct -import sys -import weakref - -import py - +import py, sys, random, os, struct, operator from rpython.jit.metainterp.history import (AbstractFailDescr, AbstractDescr, BasicFailDescr, BasicFinalDescr, BoxInt, Box, BoxPtr, JitCellToken, TargetToken, - ConstInt, + ConstInt, ConstPtr, BoxFloat, ConstFloat) from rpython.jit.metainterp.resoperation import ResOperation, rop from rpython.jit.metainterp.typesystem import deref @@ -193,6 +184,7 @@ assert res == 10 def test_backends_dont_keep_loops_alive(self): + import weakref, gc self.cpu.dont_keepalive_stuff = True i0 = BoxInt() i1 = BoxInt() @@ -3726,23 +3718,19 @@ targettoken1 = TargetToken() targettoken2 = TargetToken() faildescr = BasicFailDescr(2) - jitcode = JitCode("name") - jitcode.setup(num_regs_i=1, num_regs_r=0, num_regs_f=0) operations = [ - ResOperation(rop.ENTER_FRAME, [ConstInt(-1)], None, descr=jitcode), ResOperation(rop.LABEL, [i0], None, descr=targettoken1), ResOperation(rop.INT_ADD, [i0, ConstInt(1)], i1), ResOperation(rop.INT_LE, [i1, ConstInt(9)], i2), - ResOperation(rop.RESUME_PUT, [i1, ConstInt(0), ConstInt(0)], None), ResOperation(rop.GUARD_TRUE, [i2], None, descr=faildescr), ResOperation(rop.LABEL, [i1], None, descr=targettoken2), - ResOperation(rop.RESUME_PUT, [i1, ConstInt(0), ConstInt(0)], None), ResOperation(rop.INT_GE, [i1, ConstInt(0)], i3), ResOperation(rop.GUARD_TRUE, [i3], None, descr=BasicFailDescr(3)), - ResOperation(rop.LEAVE_FRAME, [], None), ResOperation(rop.JUMP, [i1], None, descr=targettoken1), - ] + ] inputargs = [i0] + operations[3].setfailargs([i1]) + operations[6].setfailargs([i1]) self.cpu.compile_loop(None, inputargs, operations, looptoken) deadframe = self.cpu.execute_token(looptoken, 2) From noreply at buildbot.pypy.org Wed Sep 25 22:39:49 2013 From: noreply at buildbot.pypy.org (arigo) Date: Wed, 25 Sep 2013 22:39:49 +0200 (CEST) Subject: [pypy-commit] benchmarks default: hacked. Got this error *once*, don't want to care Message-ID: <20130925203949.344A61C0204@cobra.cs.uni-duesseldorf.de> Author: Armin Rigo Branch: Changeset: r232:33e45da0c853 Date: 2013-09-25 22:39 +0200 http://bitbucket.org/pypy/benchmarks/changeset/33e45da0c853/ Log: hacked. Got this error *once*, don't want to care diff --git a/unladen_swallow/perf.py b/unladen_swallow/perf.py --- a/unladen_swallow/perf.py +++ b/unladen_swallow/perf.py @@ -676,7 +676,11 @@ print base_times print "Changed:" print changed_times - raise Exception("length did not match") + # XXX hacked. Got this error *once*, don't want to care + print "WARNING: length did not match" + l = min(len(base_times), len(changed_times)) + base_times = base_times[:l] + changed_times = changed_times[:l] if options.no_statistics: return RawResult(base_times, changed_times) if len(base_times) == 1: From noreply at buildbot.pypy.org Thu Sep 26 00:11:53 2013 From: noreply at buildbot.pypy.org (alex_gaynor) Date: Thu, 26 Sep 2013 00:11:53 +0200 (CEST) Subject: [pypy-commit] pypy default: Remove an unused local var Message-ID: <20130925221153.0849C1C02AE@cobra.cs.uni-duesseldorf.de> Author: Alex Gaynor Branch: Changeset: r67105:44d4583f2bff Date: 2013-09-25 15:11 -0700 http://bitbucket.org/pypy/pypy/changeset/44d4583f2bff/ Log: Remove an unused local var diff --git a/rpython/jit/metainterp/optimizeopt/__init__.py b/rpython/jit/metainterp/optimizeopt/__init__.py --- a/rpython/jit/metainterp/optimizeopt/__init__.py +++ b/rpython/jit/metainterp/optimizeopt/__init__.py @@ -32,7 +32,6 @@ 'please fix rlib/jit.py to say ENABLE_ALL_OPTS = %r' % (ALL_OPTS_NAMES,)) def build_opt_chain(metainterp_sd, enable_opts): - config = metainterp_sd.config optimizations = [] unroll = 'unroll' in enable_opts # 'enable_opts' is normally a dict for name, opt in unroll_all_opts: From noreply at buildbot.pypy.org Thu Sep 26 03:05:59 2013 From: noreply at buildbot.pypy.org (alex_gaynor) Date: Thu, 26 Sep 2013 03:05:59 +0200 (CEST) Subject: [pypy-commit] extradoc extradoc: Another item Message-ID: <20130926010559.E48061C0204@cobra.cs.uni-duesseldorf.de> Author: Alex Gaynor Branch: extradoc Changeset: r5062:525e40c1aa52 Date: 2013-09-25 18:05 -0700 http://bitbucket.org/pypy/extradoc/changeset/525e40c1aa52/ Log: Another item diff --git a/planning/jit.txt b/planning/jit.txt --- a/planning/jit.txt +++ b/planning/jit.txt @@ -45,6 +45,9 @@ (SETINTERIORFIELD, GETINTERIORFIELD). This is needed for the previous item to fully work. +- {}.update({}) is not fully unrolled and constant folded because HeapCache + loses track of values in virtual-to-virtual ARRAY_COPY calls. + OPTIMIZATIONS ------------- From noreply at buildbot.pypy.org Thu Sep 26 11:17:39 2013 From: noreply at buildbot.pypy.org (arigo) Date: Thu, 26 Sep 2013 11:17:39 +0200 (CEST) Subject: [pypy-commit] pypy stmgc-c4: Update to stmgc/6184784a65a0 Message-ID: <20130926091739.CD13B1C033D@cobra.cs.uni-duesseldorf.de> Author: Armin Rigo Branch: stmgc-c4 Changeset: r67106:dedb55addb8d Date: 2013-09-26 08:20 +0200 http://bitbucket.org/pypy/pypy/changeset/dedb55addb8d/ Log: Update to stmgc/6184784a65a0 diff --git a/rpython/translator/stm/src_stm/dbgmem.c b/rpython/translator/stm/src_stm/dbgmem.c --- a/rpython/translator/stm/src_stm/dbgmem.c +++ b/rpython/translator/stm/src_stm/dbgmem.c @@ -15,6 +15,7 @@ static char *zone_start, *zone_current = NULL, *zone_end = NULL; static signed char accessible_pages[MMAP_TOTAL / PAGE_SIZE] = {0}; +int stm_use_mprotect = 1; static void _stm_dbgmem(void *p, size_t sz, int prot) { @@ -25,9 +26,11 @@ intptr_t align = ((intptr_t)p) & (PAGE_SIZE-1); p = ((char *)p) - align; sz += align; - dprintf(("dbgmem: %p, %ld, %d\n", p, (long)sz, prot)); - int err = mprotect(p, sz, prot); - assert(err == 0); + if (stm_use_mprotect) { + dprintf(("dbgmem: %p, %ld, %d\n", p, (long)sz, prot)); + int err = mprotect(p, sz, prot); + assert(err == 0); + } } void *stm_malloc(size_t sz) @@ -37,7 +40,7 @@ #ifdef _GC_MEMPROTECT pthread_mutex_lock(&malloc_mutex); if (zone_current == NULL) { - zone_start = mmap(NULL, MMAP_TOTAL, PROT_NONE, + zone_start = mmap(NULL, MMAP_TOTAL, PROT_READ | PROT_WRITE, MAP_PRIVATE | MAP_ANONYMOUS, -1, 0); if (zone_start == NULL || zone_start == MAP_FAILED) { stm_fatalerror("not enough memory: mmap() failed\n"); diff --git a/rpython/translator/stm/src_stm/et.c b/rpython/translator/stm/src_stm/et.c --- a/rpython/translator/stm/src_stm/et.c +++ b/rpython/translator/stm/src_stm/et.c @@ -1017,7 +1017,12 @@ // jump back to the setjmp_buf (this call does not return) stm_stop_sharedlock(); - longjmp(*d->setjmp_buf, 1); + if (d->longjmp_callback != NULL) + d->longjmp_callback(d->setjmp_buf); + else + longjmp(*(jmp_buf *)d->setjmp_buf, 1); + + stm_fatalerror("longjmp() call should not return"); } void AbortTransactionAfterCollect(struct tx_descriptor *d, int reason) @@ -1084,12 +1089,13 @@ gcptrlist_clear(&d->abortinfo); } -void BeginTransaction(jmp_buf* buf) +void stm_begin_transaction(void *buf, void (*longjmp_callback)(void *)) { struct tx_descriptor *d = thread_descriptor; init_transaction(d); d->active = 1; d->setjmp_buf = buf; + d->longjmp_callback = longjmp_callback; d->old_thread_local_obj = stm_thread_local_obj; d->start_time = GetGlobalCurTime(d); update_reads_size_limit(d); 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 @@ -160,7 +160,8 @@ struct tx_descriptor { struct tx_public_descriptor *public_descriptor; revision_t public_descriptor_index; - jmp_buf *setjmp_buf; + void *setjmp_buf; + void(*longjmp_callback)(void *); revision_t start_time; revision_t my_lock; gcptr *shadowstack; @@ -206,7 +207,6 @@ /************************************************************/ -void BeginTransaction(jmp_buf *); void BeginInevitableTransaction(void); /* must save roots around this call */ void CommitTransaction(void); /* must save roots around this call */ void BecomeInevitable(const char *why); /* must save roots around this call */ diff --git a/rpython/translator/stm/src_stm/revision b/rpython/translator/stm/src_stm/revision --- a/rpython/translator/stm/src_stm/revision +++ b/rpython/translator/stm/src_stm/revision @@ -1,1 +1,1 @@ -111c09337109 +6184784a65a0 diff --git a/rpython/translator/stm/src_stm/stmgc.h b/rpython/translator/stm/src_stm/stmgc.h --- a/rpython/translator/stm/src_stm/stmgc.h +++ b/rpython/translator/stm/src_stm/stmgc.h @@ -122,6 +122,12 @@ void stm_begin_inevitable_transaction(void); void stm_become_inevitable(const char *reason); +/* specialized usage: for custom setjmp/longjmp implementation. + Must save roots around calls. */ +void stm_begin_transaction(void *buf, void (*longjmp_callback)(void *)); +void stm_transaction_break(void *buf, void (*longjmp_callback)(void *)); +void stm_invalidate_jmp_buf(void *buf); + /* debugging: check if we're currently running a transaction or not. */ int stm_in_transaction(void); diff --git a/rpython/translator/stm/src_stm/stmsync.c b/rpython/translator/stm/src_stm/stmsync.c --- a/rpython/translator/stm/src_stm/stmsync.c +++ b/rpython/translator/stm/src_stm/stmsync.c @@ -177,7 +177,7 @@ d->reads_size_limit_nonatomic = limit; } if (!d->atomic) { - BeginTransaction(&_jmpbuf); + stm_begin_transaction(&_jmpbuf, NULL); } else { /* atomic transaction: a common case is that callback() returned @@ -214,6 +214,35 @@ assert(stm_shadowstack == v_saved_value); } +void stm_transaction_break(void *buf, void (*longjmp_callback)(void *)) +{ /* must save roots around this call */ + struct tx_descriptor *d = thread_descriptor; + if (d->atomic) { + assert(d->active >= 1); + stm_possible_safe_point(); + } + else { + CommitTransaction(); + if (d->active != 2) { + unsigned long limit = d->reads_size_limit_nonatomic; + if (limit != 0 && limit < (stm_regular_length_limit >> 1)) + limit = (limit << 1) | 1; + else + limit = stm_regular_length_limit; + d->reads_size_limit_nonatomic = limit; + } + stm_begin_transaction(buf, longjmp_callback); + } +} + +void stm_invalidate_jmp_buf(void *buf) +{ /* must save roots around this call */ + struct tx_descriptor *d = thread_descriptor; + if (d->setjmp_buf == buf) { + BecomeInevitable("stm_invalidate_jmp_buf with atomic"); + } +} + void stm_commit_transaction(void) { /* must save roots around this call */ struct tx_descriptor *d = thread_descriptor; From noreply at buildbot.pypy.org Thu Sep 26 11:17:41 2013 From: noreply at buildbot.pypy.org (arigo) Date: Thu, 26 Sep 2013 11:17:41 +0200 (CEST) Subject: [pypy-commit] pypy stmgc-c4: Try to revert module/signal and use a 'stm_dont_track_raw_accesses' Message-ID: <20130926091741.4B2161C033D@cobra.cs.uni-duesseldorf.de> Author: Armin Rigo Branch: stmgc-c4 Changeset: r67107:4c16a18b6a43 Date: 2013-09-26 08:56 +0200 http://bitbucket.org/pypy/pypy/changeset/4c16a18b6a43/ Log: Try to revert module/signal and use a 'stm_dont_track_raw_accesses' flag on the result of pypysig_getaddr_occurred() instead. diff --git a/pypy/interpreter/executioncontext.py b/pypy/interpreter/executioncontext.py --- a/pypy/interpreter/executioncontext.py +++ b/pypy/interpreter/executioncontext.py @@ -345,7 +345,7 @@ self.fired_actions.append(action) # set the ticker to -1 in order to force action_dispatcher() # to run at the next possible bytecode - self.reset_ticker(-1) + self.rearm_ticker() def register_periodic_action(self, action, use_bytecode_counter): """NOT_RPYTHON: @@ -378,7 +378,7 @@ elif interval > MAX: interval = MAX self.checkinterval_scaled = interval * TICK_COUNTER_STEP - self.reset_ticker(-1) + self.rearm_ticker() if self.setcheckinterval_callback is not None: self.setcheckinterval_callback() @@ -415,6 +415,9 @@ def reset_ticker(self, value): self._ticker = value + def rearm_ticker(self): + self._ticker = -1 + def decrement_ticker(self, by): value = self._ticker if self.has_bytecode_counter: # this 'if' is constant-folded 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 @@ -46,10 +46,5 @@ space.check_signal_action = interp_signal.CheckSignalAction(space) space.actionflag.register_periodic_action(space.check_signal_action, use_bytecode_counter=False) - # - if space.config.translation.stm: - from pypy.module.signal.stmactionflag import SignalActionFlag - else: - from pypy.module.signal.actionflag import SignalActionFlag - space.actionflag.__class__ = SignalActionFlag + space.actionflag.__class__ = interp_signal.SignalActionFlag # xxx yes I know the previous line is a hack diff --git a/pypy/module/signal/actionflag.py b/pypy/module/signal/actionflag.py deleted file mode 100644 --- a/pypy/module/signal/actionflag.py +++ /dev/null @@ -1,33 +0,0 @@ -from pypy.interpreter.executioncontext import AbstractActionFlag -from rpython.rlib import jit -from rpython.rlib.rsignal import pypysig_getaddr_occurred - - -class SignalActionFlag(AbstractActionFlag): - # This class uses the C-level pypysig_counter variable as the tick - # counter. The C-level signal handler will reset it to -1 whenever - # a signal is received. This causes CheckSignalAction.perform() to - # be called. - - def get_ticker(self): - p = pypysig_getaddr_occurred() - return p.c_value - - def reset_ticker(self, value): - p = pypysig_getaddr_occurred() - p.c_value = value - - def rearm_ticker(self): - p = pypysig_getaddr_occurred() - p.c_value = -1 - - def decrement_ticker(self, by): - p = pypysig_getaddr_occurred() - value = p.c_value - if self.has_bytecode_counter: # this 'if' is constant-folded - if jit.isconstant(by) and by == 0: - pass # normally constant-folded too - else: - value -= by - p.c_value = value - return value diff --git a/pypy/module/signal/interp_signal.py b/pypy/module/signal/interp_signal.py --- a/pypy/module/signal/interp_signal.py +++ b/pypy/module/signal/interp_signal.py @@ -4,7 +4,8 @@ import sys from pypy.interpreter.error import OperationError, exception_from_errno -from pypy.interpreter.executioncontext import AsyncAction, PeriodicAsyncAction +from pypy.interpreter.executioncontext import (AsyncAction, AbstractActionFlag, + PeriodicAsyncAction) from pypy.interpreter.gateway import unwrap_spec from rpython.rlib import jit, rposix, rgc @@ -17,6 +18,40 @@ WIN32 = sys.platform == 'win32' +class SignalActionFlag(AbstractActionFlag): + # This class uses the C-level pypysig_counter variable as the tick + # counter. The C-level signal handler will reset it to -1 whenever + # a signal is received. This causes CheckSignalAction.perform() to + # be called. + + def get_ticker(self): + p = pypysig_getaddr_occurred() + return p.c_value + + def reset_ticker(self, value): + # STM: explicit manipulation of the counter needs to turn the + # transaction inevitable. We don't turn it inevitable in + # decrement_ticker() or if a real signal is received, but + # we turn it inevitable when this condition is detected + # and we reset a value >= 0. + pypysig_set_occurred(value) + + def rearm_ticker(self): + p = pypysig_getaddr_occurred() + p.c_value = -1 + + def decrement_ticker(self, by): + p = pypysig_getaddr_occurred() + value = p.c_value + if self.has_bytecode_counter: # this 'if' is constant-folded + if jit.isconstant(by) and by == 0: + pass # normally constant-folded too + else: + value -= by + p.c_value = value + return value + + class CheckSignalAction(PeriodicAsyncAction): """An action that is automatically invoked when a signal is received.""" @@ -170,7 +205,7 @@ space.wrap("invalid signal value")) if not space.threadlocals.signals_enabled(): raise OperationError(space.w_ValueError, - space.wrap("signal() only works in main thread " + space.wrap("signal only works in main thread " "or with __pypy__.thread.enable_signals()")) check_signum_in_range(space, signum) @@ -203,7 +238,7 @@ if not space.threadlocals.signals_enabled(): raise OperationError( space.w_ValueError, - space.wrap("set_wakeup_fd() only works in main thread " + space.wrap("set_wakeup_fd only works in main thread " "or with __pypy__.thread.enable_signals()")) old_fd = pypysig_set_wakeup_fd(fd) return space.wrap(intmask(old_fd)) diff --git a/pypy/module/signal/stmactionflag.py b/pypy/module/signal/stmactionflag.py deleted file mode 100644 --- a/pypy/module/signal/stmactionflag.py +++ /dev/null @@ -1,43 +0,0 @@ -from pypy.interpreter.executioncontext import AbstractActionFlag -from rpython.rlib import jit, rstm -from rpython.rlib.objectmodel import we_are_translated -from rpython.rlib.rsignal import pypysig_get_occurred, pypysig_set_occurred - - -class SignalActionFlag(AbstractActionFlag): - # This is mostly a copy of actionflag.py, but written in a way - # that doesn't force atomic transactions --- but isn't very JIT - # friendly yet. - - def get_ticker(self): - if we_are_translated(): - return pypysig_get_occurred() - else: - return 42 - - def reset_ticker(self, value): - if we_are_translated(): - # explicit manipulation of the counter needs to turn the - # transaction inevitable. We don't turn it inevitable in - # decrement_ticker() or if a real signal is received, but - # we turn it inevitable when this condition is detected - # and we reset a value >= 0. - rstm.become_inevitable() - pypysig_set_occurred(value) - - def rearm_ticker(self): - if we_are_translated(): - pypysig_set_occurred(-1) - - def decrement_ticker(self, by): - if we_are_translated(): - value = pypysig_get_occurred() - if self.has_bytecode_counter: # this 'if' is constant-folded - if jit.isconstant(by) and by == 0: - pass # normally constant-folded too - else: - value -= by - pypysig_set_occurred(value) - return value - else: - return 42 diff --git a/rpython/rlib/rsignal.py b/rpython/rlib/rsignal.py --- a/rpython/rlib/rsignal.py +++ b/rpython/rlib/rsignal.py @@ -86,20 +86,20 @@ # don't use rffi.LONGP because the JIT doesn't support raw arrays so far struct_name = 'pypysig_long_struct' -LONG_STRUCT = lltype.Struct(struct_name, ('c_value', lltype.Signed), - hints={'c_name' : struct_name, 'external' : 'C'}) +_LONG_STRUCT = lltype.Struct(struct_name, ('c_value', lltype.Signed), + hints={'c_name' : struct_name, 'external' : 'C', + 'stm_dont_track_raw_accesses': True}) del struct_name pypysig_getaddr_occurred = external('pypysig_getaddr_occurred', [], - lltype.Ptr(LONG_STRUCT), _nowrapper=True, + lltype.Ptr(_LONG_STRUCT), _nowrapper=True, transactionsafe=True, elidable_function=True) pypysig_get_occurred = external('pypysig_get_occurred', [], lltype.Signed, _nowrapper=True, transactionsafe=True) pypysig_set_occurred = external('pypysig_set_occurred', [lltype.Signed], - lltype.Void, _nowrapper=True, - transactionsafe=True) + lltype.Void, _nowrapper=True) c_alarm = external('alarm', [rffi.INT], rffi.INT) c_pause = external('pause', [], rffi.INT, threadsafe=True) c_siginterrupt = external('siginterrupt', [rffi.INT, rffi.INT], rffi.INT) From noreply at buildbot.pypy.org Thu Sep 26 11:17:42 2013 From: noreply at buildbot.pypy.org (arigo) Date: Thu, 26 Sep 2013 11:17:42 +0200 (CEST) Subject: [pypy-commit] pypy stmgc-c4: Port the trick from pypysig_getaddr_occurred() to the two other functions Message-ID: <20130926091742.B07B41C033D@cobra.cs.uni-duesseldorf.de> Author: Armin Rigo Branch: stmgc-c4 Changeset: r67108:d63ff723e98d Date: 2013-09-26 09:06 +0200 http://bitbucket.org/pypy/pypy/changeset/d63ff723e98d/ Log: Port the trick from pypysig_getaddr_occurred() to the two other functions (which were not used far). diff --git a/rpython/translator/c/src/signals.c b/rpython/translator/c/src/signals.c --- a/rpython/translator/c/src/signals.c +++ b/rpython/translator/c/src/signals.c @@ -43,6 +43,19 @@ return (void *)(&pypysig_counter); } +#undef pypysig_get_occurred +long pypysig_get_occurred(void) +{ + return pypysig_counter.value; +} + +#undef pypysig_set_occurred +void pypysig_set_occurred(long nvalue) +{ + pypysig_counter.value = nvalue; +} + + void pypysig_ignore(int signum) { #ifdef SA_RESTART diff --git a/rpython/translator/c/src/signals.h b/rpython/translator/c/src/signals.h --- a/rpython/translator/c/src/signals.h +++ b/rpython/translator/c/src/signals.h @@ -24,9 +24,10 @@ use macros when compiling as a stand-alone program, but still export a function with the correct name for testing */ void *pypysig_getaddr_occurred(void); +long pypysig_get_occurred(void); +void pypysig_set_occurred(long); #define pypysig_getaddr_occurred() ((void *)(&pypysig_counter)) - -static long pypysig_get_occurred(void) { return pypysig_counter.value; } -static void pypysig_set_occurred(long value) { pypysig_counter.value = value; } +#define pypysig_get_occurred() (pypysig_counter.value) +#define pypysig_set_occurred(nv) (pypysig_counter.value = nv) #endif From noreply at buildbot.pypy.org Thu Sep 26 11:17:43 2013 From: noreply at buildbot.pypy.org (arigo) Date: Thu, 26 Sep 2013 11:17:43 +0200 (CEST) Subject: [pypy-commit] pypy stmgc-c4: Don't force inevitable when doing a raw getfield/setfield Message-ID: <20130926091743.DA38C1C033D@cobra.cs.uni-duesseldorf.de> Author: Armin Rigo Branch: stmgc-c4 Changeset: r67109:64209c0ce0e5 Date: 2013-09-26 10:15 +0200 http://bitbucket.org/pypy/pypy/changeset/64209c0ce0e5/ Log: Don't force inevitable when doing a raw getfield/setfield if the struct has 'stm_dont_track_raw_accesses'. 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 @@ -87,12 +87,15 @@ offset = 0 # help translation field_size = 0 flag = '\x00' + stm_dont_track_raw_accesses = False - def __init__(self, name, offset, field_size, flag): + def __init__(self, name, offset, field_size, flag, + stm_dont_track_raw_accesses=False): self.name = name self.offset = offset self.field_size = field_size self.flag = flag + self.stm_dont_track_raw_accesses = stm_dont_track_raw_accesses def is_pointer_field(self): return self.flag == FLAG_POINTER @@ -120,7 +123,10 @@ FIELDTYPE = getattr(STRUCT, fieldname) flag = get_type_flag(FIELDTYPE) name = '%s.%s' % (STRUCT._name, fieldname) - fielddescr = FieldDescr(name, offset, size, flag) + stm_dont_track_raw_accesses = STRUCT._hints.get( + 'stm_dont_track_raw_accesses', False) + fielddescr = FieldDescr(name, offset, size, flag, + stm_dont_track_raw_accesses) cachedict = cache.setdefault(STRUCT, {}) cachedict[fieldname] = fielddescr return fielddescr diff --git a/rpython/jit/backend/llsupport/stmrewrite.py b/rpython/jit/backend/llsupport/stmrewrite.py --- a/rpython/jit/backend/llsupport/stmrewrite.py +++ b/rpython/jit/backend/llsupport/stmrewrite.py @@ -127,6 +127,10 @@ rop.COPYUNICODECONTENT): self.handle_copystrcontent(op) continue + # ---------- raw getfields and setfields ---------- + if op.getopnum() in (rop.GETFIELD_RAW, rop.SETFIELD_RAW): + if self.maybe_handle_raw_accesses(op): + continue # ---------- labels ---------- if op.getopnum() == rop.LABEL: self.known_category.clear() @@ -241,3 +245,12 @@ def handle_ptr_eq(self, op): self.newops.append(op) + + def maybe_handle_raw_accesses(self, op): + from rpython.jit.backend.llsupport.descr import FieldDescr + descr = op.getdescr() + assert isinstance(descr, FieldDescr) + if descr.stm_dont_track_raw_accesses: + self.newops.append(op) + return True + return False diff --git a/rpython/jit/backend/llsupport/test/test_descr.py b/rpython/jit/backend/llsupport/test/test_descr.py --- a/rpython/jit/backend/llsupport/test/test_descr.py +++ b/rpython/jit/backend/llsupport/test/test_descr.py @@ -118,6 +118,16 @@ assert descr.flag == FLAG_FLOAT assert descr.field_size == 8 +def test_get_field_descr_stm_dont_track_raw_accesses(): + c2 = GcCache(True) + S = lltype.Struct('S', ('x', lltype.Signed)) + T = lltype.Struct('T', ('y', lltype.Signed), + hints={'stm_dont_track_raw_accesses': True}) + descr_x = get_field_descr(c2, S, 'x') + descr_y = get_field_descr(c2, T, 'y') + assert descr_x.stm_dont_track_raw_accesses == False + assert descr_y.stm_dont_track_raw_accesses == True + def test_get_array_descr(): U = lltype.Struct('U') diff --git a/rpython/jit/backend/llsupport/test/test_stmrewrite.py b/rpython/jit/backend/llsupport/test/test_stmrewrite.py --- a/rpython/jit/backend/llsupport/test/test_stmrewrite.py +++ b/rpython/jit/backend/llsupport/test/test_stmrewrite.py @@ -507,6 +507,21 @@ jump(i3, i4) """) + def test_getfield_raw_stm_dont_track_raw_accesses(self): + c1 = GcCache(True) + F = lltype.Struct('F', ('x', lltype.Signed), + hints={'stm_dont_track_raw_accesses': True}) + fdescr = get_field_descr(c1, F, 'x') + self.check_rewrite(""" + [i1] + i2 = getfield_raw(i1, descr=fdescr) + jump(i2) + """, """ + [i1] + i2 = getfield_raw(i1, descr=fdescr) + jump(i2) + """, fdescr=fdescr) + def test_getfield_raw_over_label(self): self.check_rewrite(""" [i1, i2] From noreply at buildbot.pypy.org Thu Sep 26 11:17:45 2013 From: noreply at buildbot.pypy.org (arigo) Date: Thu, 26 Sep 2013 11:17:45 +0200 (CEST) Subject: [pypy-commit] pypy stmgc-c4: in-progress: call stm_transaction_break() from within the jit-produced Message-ID: <20130926091745.23B401C033D@cobra.cs.uni-duesseldorf.de> Author: Armin Rigo Branch: stmgc-c4 Changeset: r67110:65220778d003 Date: 2013-09-26 11:16 +0200 http://bitbucket.org/pypy/pypy/changeset/65220778d003/ Log: in-progress: call stm_transaction_break() from within the jit- produced code 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 @@ -91,8 +91,9 @@ self._build_b_slowpath(d, True) self._build_b_slowpath(d, False, for_frame=True) # only for stm: - if hasattr(gc_ll_descr, 'stm_ptr_eq_FUNCPTR'): + if gc_ll_descr.stm: self._build_ptr_eq_slowpath() + self._build_stm_longjmp_callback() else: self.ptr_eq_slowpath = None # only one of those diff --git a/rpython/jit/backend/llsupport/stmrewrite.py b/rpython/jit/backend/llsupport/stmrewrite.py --- a/rpython/jit/backend/llsupport/stmrewrite.py +++ b/rpython/jit/backend/llsupport/stmrewrite.py @@ -137,9 +137,14 @@ self.always_inevitable = False self.newops.append(op) continue - # ---------- jump, finish, other ignored ops ---------- - if op.getopnum() in (rop.JUMP, - rop.FINISH, + # ---------- jumps ---------- + if op.getopnum() == rop.JUMP: + self.newops.append( + ResOperation(rop.STM_TRANSACTION_BREAK, [], None)) + self.newops.append(op) + continue + # ---------- finish, other ignored ops ---------- + if op.getopnum() in (rop.FINISH, rop.FORCE_TOKEN, rop.READ_TIMESTAMP, rop.MARK_OPAQUE_PTR, 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 @@ -16,6 +16,8 @@ # +--------------------+ <== aligned to 16 bytes # | return address | # +--------------------+ +# | STM resume buf | (4 extra words, only with STM) +# +--------------------+ # | saved regs | # +--------------------+ # | scratch | @@ -42,3 +44,5 @@ JITFRAME_FIXED_SIZE = 28 # 13 GPR + 15 XMM assert PASS_ON_MY_FRAME >= 12 # asmgcc needs at least JIT_USE_WORDS + 3 + +STM_RESUME_BUF = 4 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 @@ -18,7 +18,7 @@ from rpython.jit.backend.llsupport.regalloc import (get_scale, valid_addressing_size) from rpython.jit.backend.x86.arch import (FRAME_FIXED_SIZE, WORD, IS_X86_64, JITFRAME_FIXED_SIZE, IS_X86_32, - PASS_ON_MY_FRAME) + PASS_ON_MY_FRAME, STM_RESUME_BUF) from rpython.jit.backend.x86.regloc import (eax, ecx, edx, ebx, esp, ebp, esi, xmm0, xmm1, xmm2, xmm3, xmm4, xmm5, xmm6, xmm7, r8, r9, r10, r11, edi, r12, r13, r14, r15, X86_64_SCRATCH_REG, X86_64_XMM_SCRATCH_REG, @@ -290,7 +290,6 @@ rgc.cast_instance_to_gcref(self.cpu.propagate_exception_descr)) ofs = self.cpu.get_ofs_of_frame_field('jf_descr') self.mc.MOV(RawEbpLoc(ofs), imm(propagate_exception_descr)) - self.mc.MOV_rr(eax.value, ebp.value) # self._call_footer() rawstart = self.mc.materialize(self.cpu.asmmemmgr, []) @@ -299,8 +298,7 @@ def _get_stm_tl(self, adr): """Makes 'adr' relative to threadlocal-base if we run in STM. - Before using such a relative address, call - self._stm_tl_segment_prefix_if_necessary.""" + Before using such a relative address, call _tl_segment_if_stm().""" if self.cpu.gc_ll_descr.stm and we_are_translated(): # only for STM and not during tests result = adr - stmtlocal.threadlocal_base() @@ -313,7 +311,7 @@ in STM and not during testing.""" if self.cpu.gc_ll_descr.stm and we_are_translated(): stmtlocal.tl_segment_prefix(mc) - + def _build_stack_check_slowpath(self): if self.cpu.gc_ll_descr.stm: return # XXX no stack check on STM for now @@ -553,6 +551,34 @@ else: descr.set_b_slowpath(withcards + 2 * withfloats, rawstart) + + def _build_stm_longjmp_callback(self): + assert self.cpu.gc_ll_descr.stm + if not we_are_translated(): + return # tests only + # + # make the stm_longjmp_callback() function, with signature + # void (*longjmp_callback)(void *stm_resume_buffer) + mc = codebuf.MachineCodeBlockWrapper() + # + # 'edi' contains the stm resume buffer, so the new stack + # location that we have to enforce is 'edi - FRAME_FIXED_SIZE * WORD'. + if IS_X86_32: + mc.MOV_rs(edi.value, WORD) # first argument + mc.MOV_rr(esp.value, edi.value) + mc.SUB_ri(esp.value, FRAME_FIXED_SIZE * WORD) + # + # must restore 'ebp' from its saved value in the shadowstack + self._reload_frame_if_necessary(mc) + # + # jump to the place saved in the stm_resume_buffer + # (to "HERE" in genop_stm_transaction_break()) + mc.MOV_rs(eax.value, FRAME_FIXED_SIZE * WORD) + mc.PUSH_r(eax.value) + mc.JMP_r(eax.value) + self.stm_longjmp_callback_addr = mc.materialize(self.cpu.asmmemmgr, []) + + @rgc.no_release_gil def assemble_loop(self, loopname, inputargs, operations, looptoken, log, logger=None): @@ -848,13 +874,19 @@ frame_depth = max(frame_depth, target_frame_depth) return frame_depth + def _get_whole_frame_size(self): + frame_size = FRAME_FIXED_SIZE + if self.cpu.gc_ll_descr.stm: + frame_size += STM_RESUME_BUF + return frame_size + def _call_header(self): - self.mc.SUB_ri(esp.value, FRAME_FIXED_SIZE * WORD) + self.mc.SUB_ri(esp.value, self._get_whole_frame_size() * WORD) self.mc.MOV_sr(PASS_ON_MY_FRAME * WORD, ebp.value) if IS_X86_64: self.mc.MOV_rr(ebp.value, edi.value) else: - self.mc.MOV_rs(ebp.value, (FRAME_FIXED_SIZE + 1) * WORD) + self.mc.MOV_rs(ebp.value, (self._get_whole_frame_size() + 1) * WORD) for i, loc in enumerate(self.cpu.CALLEE_SAVE_REGISTERS): self.mc.MOV_sr((PASS_ON_MY_FRAME + i + 1) * WORD, loc.value) @@ -882,6 +914,18 @@ # def _call_footer(self): + if self.cpu.gc_ll_descr.stm and we_are_translated(): + # call stm_invalidate_jmp_buf(), in case we called + # stm_transaction_break() earlier + assert IS_X86_64 + # load the address of the STM_RESUME_BUF + self.mc.LEA_rs(edi.value, FRAME_FIXED_SIZE * WORD) + fn = stmtlocal.stm_invalidate_jmp_buf_fn + self.mc.CALL(imm(self.cpu.cast_ptr_to_int(fn))) + + # the return value is the jitframe + self.mc.MOV_rr(eax.value, ebp.value) + gcrootmap = self.cpu.gc_ll_descr.gcrootmap if gcrootmap and gcrootmap.is_shadow_stack: self._call_footer_shadowstack(gcrootmap) @@ -891,7 +935,7 @@ (i + 1 + PASS_ON_MY_FRAME) * WORD) self.mc.MOV_rs(ebp.value, PASS_ON_MY_FRAME * WORD) - self.mc.ADD_ri(esp.value, FRAME_FIXED_SIZE * WORD) + self.mc.ADD_ri(esp.value, self._get_whole_frame_size() * WORD) self.mc.RET() def _load_shadowstack_top_in_ebx(self, mc, gcrootmap): @@ -2071,8 +2115,6 @@ mc.MOV_br(ofs2, eax.value) mc.POP(eax) mc.MOV_br(ofs, eax.value) - # the return value is the jitframe - mc.MOV_rr(eax.value, ebp.value) self._call_footer() rawstart = mc.materialize(self.cpu.asmmemmgr, []) @@ -2833,6 +2875,41 @@ assert isinstance(reg, RegLoc) self.mc.MOV_rr(reg.value, ebp.value) + def genop_stm_transaction_break(self, op, arglocs, result_loc): + assert self.cpu.gc_ll_descr.stm + if not we_are_translated(): + return # tests only + # "if stm_should_break_transaction()" + mc = self.mc + fn = stmtlocal.stm_should_break_transaction_fn + mc.CALL(imm(self.cpu.cast_ptr_to_int(fn))) + mc.TEST8_rr(eax.value, eax.value) + mc.J_il8(rx86.Conditions['Z'], 0) + jz_location = mc.get_relative_pos() + # + # call stm_transaction_break() with the address of the + # STM_RESUME_BUF and the custom longjmp function + mc.LEA_rs(edi.value, FRAME_FIXED_SIZE * WORD) + mc.MOV_ri(esi.value, self.stm_longjmp_callback_addr) + fn = stmtlocal.stm_transaction_break_fn + mc.CALL(imm(self.cpu.cast_ptr_to_int(fn))) + # + # Fill the stm resume buffer. Don't do it before the call! + # The previous transaction may still be aborted during the call + # above, so we need the old content of the buffer! + # For now the buffer only contains the address of the resume + # point in this piece of code (at "HERE"). + mc.CALL_l(0) + # "HERE" + mc.POP_r(eax.value) + mc.MOV_sr(FRAME_FIXED_SIZE * WORD, eax.value) + # + # patch the JZ above + offset = mc.get_relative_pos() - jz_location + assert 0 < offset <= 127 + mc.overwrite(jz_location-1, chr(offset)) + + genop_discard_list = [Assembler386.not_implemented_op_discard] * rop._LAST genop_list = [Assembler386.not_implemented_op] * rop._LAST genop_llong_list = {} 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 @@ -11,7 +11,7 @@ RegisterManager, TempBox, compute_vars_longevity, is_comparison_or_ovf_op) from rpython.jit.backend.x86 import rx86 from rpython.jit.backend.x86.arch import (WORD, JITFRAME_FIXED_SIZE, IS_X86_32, - IS_X86_64) + IS_X86_64, FRAME_FIXED_SIZE) from rpython.jit.backend.x86.jump import remap_frame_layout_mixed from rpython.jit.backend.x86.regloc import (FrameLoc, RegLoc, ConstFloatLoc, FloatImmedLoc, ImmedLoc, imm, imm0, imm1, ecx, eax, edx, ebx, esi, edi, @@ -1267,6 +1267,13 @@ if isinstance(loc, FrameLoc): self.fm.hint_frame_locations[box] = loc + def consider_stm_transaction_break(self, op): + # XXX use the extra 3 words in the stm resume buffer to save + # up to 3 registers, too. For now we just flush them all. + self.xrm.before_call(save_all_regs=1) + self.rm.before_call(save_all_regs=1) + self.perform(op, [], None) + def consider_jump(self, op): assembler = self.assembler assert self.jump_target_descr is None diff --git a/rpython/jit/backend/x86/stmtlocal.py b/rpython/jit/backend/x86/stmtlocal.py --- a/rpython/jit/backend/x86/stmtlocal.py +++ b/rpython/jit/backend/x86/stmtlocal.py @@ -1,4 +1,4 @@ -from rpython.rtyper.lltypesystem import lltype, rffi +from rpython.rtyper.lltypesystem import lltype, rffi, llmemory from rpython.translator.tool.cbuild import ExternalCompilationInfo from rpython.jit.backend.x86.arch import WORD @@ -32,3 +32,18 @@ mc.writechar('\x65') # %gs: else: mc.writechar('\x64') # %fs: + + +# special STM functions called directly by the JIT backend +stm_should_break_transaction_fn = rffi.llexternal( + 'stm_should_break_transaction', + [], lltype.Bool, + sandboxsafe=True, _nowrapper=True, transactionsafe=True) +stm_transaction_break_fn = rffi.llexternal( + 'stm_transaction_break', + [llmemory.Address, llmemory.Address], lltype.Void, + sandboxsafe=True, _nowrapper=True, transactionsafe=True) +stm_invalidate_jmp_buf_fn = rffi.llexternal( + 'stm_invalidate_jmp_buf', + [llmemory.Address], lltype.Void, + sandboxsafe=True, _nowrapper=True, transactionsafe=True) 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 @@ -347,6 +347,7 @@ rop.CALL_MALLOC_NURSERY_VARSIZE, rop.CALL_MALLOC_NURSERY_VARSIZE_FRAME, rop.LABEL, + rop.STM_TRANSACTION_BREAK, ): # list of opcodes never executed by pyjitpl continue raise AssertionError("missing %r" % (key,)) 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 @@ -510,6 +510,7 @@ 'QUASIIMMUT_FIELD/1d', # [objptr], descr=SlowMutateDescr 'RECORD_KNOWN_CLASS/2', # [objptr, clsptr] 'KEEPALIVE/1', + 'STM_TRANSACTION_BREAK/0', '_CANRAISE_FIRST', # ----- start of can_raise operations ----- '_CALL_FIRST', From noreply at buildbot.pypy.org Thu Sep 26 11:53:47 2013 From: noreply at buildbot.pypy.org (arigo) Date: Thu, 26 Sep 2013 11:53:47 +0200 (CEST) Subject: [pypy-commit] pypy stmgc-c4: Fix Message-ID: <20130926095347.719631C1052@cobra.cs.uni-duesseldorf.de> Author: Armin Rigo Branch: stmgc-c4 Changeset: r67111:64ffa165f1ac Date: 2013-09-26 11:50 +0200 http://bitbucket.org/pypy/pypy/changeset/64ffa165f1ac/ Log: Fix 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 @@ -2883,7 +2883,7 @@ mc = self.mc fn = stmtlocal.stm_should_break_transaction_fn mc.CALL(imm(self.cpu.cast_ptr_to_int(fn))) - mc.TEST8_rr(eax.value, eax.value) + mc.TEST8(eax.lowest8bits(), eax.lowest8bits()) mc.J_il8(rx86.Conditions['Z'], 0) jz_location = mc.get_relative_pos() # From noreply at buildbot.pypy.org Thu Sep 26 13:51:18 2013 From: noreply at buildbot.pypy.org (arigo) Date: Thu, 26 Sep 2013 13:51:18 +0200 (CEST) Subject: [pypy-commit] stmgc default: Fix message Message-ID: <20130926115118.AF9621C033D@cobra.cs.uni-duesseldorf.de> Author: Armin Rigo Branch: Changeset: r533:ad70e2445849 Date: 2013-09-26 13:51 +0200 http://bitbucket.org/pypy/stmgc/changeset/ad70e2445849/ Log: Fix message diff --git a/c4/stmsync.c b/c4/stmsync.c --- a/c4/stmsync.c +++ b/c4/stmsync.c @@ -238,7 +238,7 @@ { /* must save roots around this call */ struct tx_descriptor *d = thread_descriptor; if (d->setjmp_buf == buf) { - BecomeInevitable("stm_invalidate_jmp_buf with atomic"); + BecomeInevitable("stm_invalidate_jmp_buf"); } } From noreply at buildbot.pypy.org Fri Sep 27 11:25:49 2013 From: noreply at buildbot.pypy.org (arigo) Date: Fri, 27 Sep 2013 11:25:49 +0200 (CEST) Subject: [pypy-commit] pypy stmgc-c4: update to stmgc/ad70e2445849 Message-ID: <20130927092549.B29CB1C15AC@cobra.cs.uni-duesseldorf.de> Author: Armin Rigo Branch: stmgc-c4 Changeset: r67112:60e07c8d14f5 Date: 2013-09-27 11:24 +0200 http://bitbucket.org/pypy/pypy/changeset/60e07c8d14f5/ Log: update to stmgc/ad70e2445849 diff --git a/rpython/translator/stm/src_stm/revision b/rpython/translator/stm/src_stm/revision --- a/rpython/translator/stm/src_stm/revision +++ b/rpython/translator/stm/src_stm/revision @@ -1,1 +1,1 @@ -6184784a65a0 +ad70e2445849 diff --git a/rpython/translator/stm/src_stm/stmsync.c b/rpython/translator/stm/src_stm/stmsync.c --- a/rpython/translator/stm/src_stm/stmsync.c +++ b/rpython/translator/stm/src_stm/stmsync.c @@ -239,7 +239,7 @@ { /* must save roots around this call */ struct tx_descriptor *d = thread_descriptor; if (d->setjmp_buf == buf) { - BecomeInevitable("stm_invalidate_jmp_buf with atomic"); + BecomeInevitable("stm_invalidate_jmp_buf"); } } From noreply at buildbot.pypy.org Fri Sep 27 13:56:50 2013 From: noreply at buildbot.pypy.org (cfbolz) Date: Fri, 27 Sep 2013 13:56:50 +0200 (CEST) Subject: [pypy-commit] pypy default: ouch, fix off-by one error in error messages Message-ID: <20130927115650.1C2DC1C00EC@cobra.cs.uni-duesseldorf.de> Author: Carl Friedrich Bolz Branch: Changeset: r67113:13cac9640162 Date: 2013-09-27 13:46 +0200 http://bitbucket.org/pypy/pypy/changeset/13cac9640162/ Log: ouch, fix off-by one error in error messages diff --git a/rpython/rlib/parsing/deterministic.py b/rpython/rlib/parsing/deterministic.py --- a/rpython/rlib/parsing/deterministic.py +++ b/rpython/rlib/parsing/deterministic.py @@ -60,7 +60,8 @@ self.args = (input, state, source_pos) def nice_error_message(self, filename=""): - result = [" File %s, line %s" % (filename, self.source_pos.lineno)] + # + 1 is because source_pos is 0-based and humans 1-based + result = [" File %s, line %s" % (filename, self.source_pos.lineno + 1)] result.append(self.input.split("\n")[self.source_pos.lineno]) result.append(" " * self.source_pos.columnno + "^") result.append("LexerError") diff --git a/rpython/rlib/parsing/parsing.py b/rpython/rlib/parsing/parsing.py --- a/rpython/rlib/parsing/parsing.py +++ b/rpython/rlib/parsing/parsing.py @@ -47,7 +47,8 @@ self.args = (source_pos, errorinformation) def nice_error_message(self, filename="", source=""): - result = [" File %s, line %s" % (filename, self.source_pos.lineno)] + # + 1 is because source_pos is 0-based and humans 1-based + result = [" File %s, line %s" % (filename, self.source_pos.lineno + 1)] if source: result.append(source.split("\n")[self.source_pos.lineno]) result.append(" " * self.source_pos.columnno + "^") diff --git a/rpython/rlib/parsing/test/test_parseerrors.py b/rpython/rlib/parsing/test/test_parseerrors.py --- a/rpython/rlib/parsing/test/test_parseerrors.py +++ b/rpython/rlib/parsing/test/test_parseerrors.py @@ -31,7 +31,7 @@ msg = excinfo.value.nice_error_message("") print msg assert msg == """\ - File , line 2 + File , line 3 'type': 'SCRIPT',$# ^ LexerError""" @@ -51,7 +51,7 @@ msg = excinfo.value.nice_error_message("", source) print msg assert msg == """\ - File , line 4 + File , line 5 'length':: '1', ^ ParseError: expected '{', 'QUOTED_STRING' or '['""" From noreply at buildbot.pypy.org Fri Sep 27 22:04:13 2013 From: noreply at buildbot.pypy.org (pjenvey) Date: Fri, 27 Sep 2013 22:04:13 +0200 (CEST) Subject: [pypy-commit] pypy py3k: raw_input -> input on py3k Message-ID: <20130927200414.028CA1C00EC@cobra.cs.uni-duesseldorf.de> Author: Philip Jenvey Branch: py3k Changeset: r67114:ee7dd757b1df Date: 2013-09-27 13:03 -0700 http://bitbucket.org/pypy/pypy/changeset/ee7dd757b1df/ Log: raw_input -> input on py3k diff --git a/lib_pypy/pyrepl/readline.py b/lib_pypy/pyrepl/readline.py --- a/lib_pypy/pyrepl/readline.py +++ b/lib_pypy/pyrepl/readline.py @@ -422,7 +422,7 @@ del sys.__raw_input__ except AttributeError: pass - return raw_input(prompt) + return input(prompt) sys.__raw_input__ = _wrapper.raw_input else: From noreply at buildbot.pypy.org Fri Sep 27 22:22:19 2013 From: noreply at buildbot.pypy.org (pjenvey) Date: Fri, 27 Sep 2013 22:22:19 +0200 (CEST) Subject: [pypy-commit] pyrepl default: be consistent w/ the console's filename: '', to match cpython Message-ID: <20130927202219.8A5AA1C00EC@cobra.cs.uni-duesseldorf.de> Author: Philip Jenvey Branch: Changeset: r237:e7bdf8a4cfde Date: 2013-04-14 14:36 -0700 http://bitbucket.org/pypy/pyrepl/changeset/e7bdf8a4cfde/ Log: be consistent w/ the console's filename: '', to match cpython diff --git a/pyrepl/python_reader.py b/pyrepl/python_reader.py --- a/pyrepl/python_reader.py +++ b/pyrepl/python_reader.py @@ -186,10 +186,10 @@ def execute(self, text): try: - # ooh, look at the hack: - code = self.compile(text, '', 'single') + # ooh, look at the hack: + code = self.compile(text, '', 'single') except (OverflowError, SyntaxError, ValueError): - self.showsyntaxerror("") + self.showsyntaxerror("") else: self.runcode(code) if sys.stdout and not sys.stdout.closed: diff --git a/pyrepl/simple_interact.py b/pyrepl/simple_interact.py --- a/pyrepl/simple_interact.py +++ b/pyrepl/simple_interact.py @@ -39,13 +39,13 @@ import code import __main__ mainmodule = mainmodule or __main__ - console = code.InteractiveConsole(mainmodule.__dict__) + console = code.InteractiveConsole(mainmodule.__dict__, filename='') def more_lines(unicodetext): # ooh, look at the hack: src = "#coding:utf-8\n"+unicodetext.encode('utf-8') try: - code = console.compile(src, '', 'single') + code = console.compile(src, '', 'single') except (OverflowError, SyntaxError, ValueError): return False else: From noreply at buildbot.pypy.org Fri Sep 27 23:37:04 2013 From: noreply at buildbot.pypy.org (arigo) Date: Fri, 27 Sep 2013 23:37:04 +0200 (CEST) Subject: [pypy-commit] stmgc default: Hackish but simple: add here the call to stm_begin_transaction(). Message-ID: <20130927213704.772191C13CF@cobra.cs.uni-duesseldorf.de> Author: Armin Rigo Branch: Changeset: r534:d78107007cab Date: 2013-09-27 23:36 +0200 http://bitbucket.org/pypy/stmgc/changeset/d78107007cab/ Log: Hackish but simple: add here the call to stm_begin_transaction(). diff --git a/c4/et.c b/c4/et.c --- a/c4/et.c +++ b/c4/et.c @@ -1017,7 +1017,10 @@ // jump back to the setjmp_buf (this call does not return) stm_stop_sharedlock(); if (d->longjmp_callback != NULL) - d->longjmp_callback(d->setjmp_buf); + { + stm_begin_transaction(d->setjmp_buf, d->longjmp_callback); + d->longjmp_callback(d->setjmp_buf); + } else longjmp(*(jmp_buf *)d->setjmp_buf, 1); From noreply at buildbot.pypy.org Fri Sep 27 23:37:59 2013 From: noreply at buildbot.pypy.org (arigo) Date: Fri, 27 Sep 2013 23:37:59 +0200 (CEST) Subject: [pypy-commit] pypy stmgc-c4: Save and restore stm_shadowstack. Message-ID: <20130927213759.205B21C13CF@cobra.cs.uni-duesseldorf.de> Author: Armin Rigo Branch: stmgc-c4 Changeset: r67115:9d966eac78e1 Date: 2013-09-27 23:32 +0200 http://bitbucket.org/pypy/pypy/changeset/9d966eac78e1/ Log: Save and restore stm_shadowstack. 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 @@ -16,7 +16,7 @@ # +--------------------+ <== aligned to 16 bytes # | return address | # +--------------------+ -# | STM resume buf | (4 extra words, only with STM) +# | STM resume buf | (16 extra bytes, only with STM) # +--------------------+ # | saved regs | # +--------------------+ @@ -45,4 +45,4 @@ assert PASS_ON_MY_FRAME >= 12 # asmgcc needs at least JIT_USE_WORDS + 3 -STM_RESUME_BUF = 4 +STM_RESUME_BUF = 16 / WORD 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 @@ -568,12 +568,18 @@ mc.MOV_rr(esp.value, edi.value) mc.SUB_ri(esp.value, FRAME_FIXED_SIZE * WORD) # + # restore the shadowstack pointer from stm_resume_buffer[1] + rst = self._get_stm_tl(gcrootmap.get_root_stack_top_addr()) + mc.MOV_rs(eax.value, (FRAME_FIXED_SIZE + 1) * WORD) + self._tl_segment_if_stm(mc) + mc.MOV_jr(rst, eax.value) + # # must restore 'ebp' from its saved value in the shadowstack self._reload_frame_if_necessary(mc) # - # jump to the place saved in the stm_resume_buffer + # jump to the place saved in stm_resume_buffer[0] # (to "HERE" in genop_stm_transaction_break()) - mc.MOV_rs(eax.value, FRAME_FIXED_SIZE * WORD) + mc.MOV_rs(eax.value, (FRAME_FIXED_SIZE + 0) * WORD) mc.PUSH_r(eax.value) mc.JMP_r(eax.value) self.stm_longjmp_callback_addr = mc.materialize(self.cpu.asmmemmgr, []) @@ -2897,12 +2903,15 @@ # Fill the stm resume buffer. Don't do it before the call! # The previous transaction may still be aborted during the call # above, so we need the old content of the buffer! - # For now the buffer only contains the address of the resume - # point in this piece of code (at "HERE"). + # The buffer contains the address of the resume point in this + # piece of code (at "HERE") at offset 0, and at offset WORD it + # contains a copy of the current shadowstack pointer. + self._load_shadowstack_top_in_ebx(mc, self.cpu.gc_ll_descr.gcrootmap) + mc.MOV_sr((FRAME_FIXED_SIZE + 1) * WORD, ebx.value) mc.CALL_l(0) # "HERE" mc.POP_r(eax.value) - mc.MOV_sr(FRAME_FIXED_SIZE * WORD, eax.value) + mc.MOV_sr((FRAME_FIXED_SIZE + 0) * WORD, eax.value) # # patch the JZ above offset = mc.get_relative_pos() - jz_location From noreply at buildbot.pypy.org Fri Sep 27 23:38:00 2013 From: noreply at buildbot.pypy.org (arigo) Date: Fri, 27 Sep 2013 23:38:00 +0200 (CEST) Subject: [pypy-commit] pypy stmgc-c4: update to stmgc/d78107007cab Message-ID: <20130927213800.5985F1C13CF@cobra.cs.uni-duesseldorf.de> Author: Armin Rigo Branch: stmgc-c4 Changeset: r67116:82cd81e41cfb Date: 2013-09-27 23:37 +0200 http://bitbucket.org/pypy/pypy/changeset/82cd81e41cfb/ Log: update to stmgc/d78107007cab diff --git a/rpython/translator/stm/src_stm/et.c b/rpython/translator/stm/src_stm/et.c --- a/rpython/translator/stm/src_stm/et.c +++ b/rpython/translator/stm/src_stm/et.c @@ -1018,7 +1018,10 @@ // jump back to the setjmp_buf (this call does not return) stm_stop_sharedlock(); if (d->longjmp_callback != NULL) - d->longjmp_callback(d->setjmp_buf); + { + stm_begin_transaction(d->setjmp_buf, d->longjmp_callback); + d->longjmp_callback(d->setjmp_buf); + } else longjmp(*(jmp_buf *)d->setjmp_buf, 1); diff --git a/rpython/translator/stm/src_stm/revision b/rpython/translator/stm/src_stm/revision --- a/rpython/translator/stm/src_stm/revision +++ b/rpython/translator/stm/src_stm/revision @@ -1,1 +1,1 @@ -ad70e2445849 +d78107007cab From noreply at buildbot.pypy.org Sat Sep 28 00:02:55 2013 From: noreply at buildbot.pypy.org (arigo) Date: Sat, 28 Sep 2013 00:02:55 +0200 (CEST) Subject: [pypy-commit] pypy stmgc-c4: fix Message-ID: <20130927220255.ED5A71C13CF@cobra.cs.uni-duesseldorf.de> Author: Armin Rigo Branch: stmgc-c4 Changeset: r67117:6dabe65e58ae Date: 2013-09-27 23:45 +0200 http://bitbucket.org/pypy/pypy/changeset/6dabe65e58ae/ Log: fix 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 @@ -569,6 +569,7 @@ mc.SUB_ri(esp.value, FRAME_FIXED_SIZE * WORD) # # restore the shadowstack pointer from stm_resume_buffer[1] + gcrootmap = self.cpu.gc_ll_descr.gcrootmap rst = self._get_stm_tl(gcrootmap.get_root_stack_top_addr()) mc.MOV_rs(eax.value, (FRAME_FIXED_SIZE + 1) * WORD) self._tl_segment_if_stm(mc) From noreply at buildbot.pypy.org Sat Sep 28 00:02:57 2013 From: noreply at buildbot.pypy.org (arigo) Date: Sat, 28 Sep 2013 00:02:57 +0200 (CEST) Subject: [pypy-commit] pypy stmgc-c4: Fix: need to correctly save the gcmap and restore the frame around Message-ID: <20130927220257.373F81C13CF@cobra.cs.uni-duesseldorf.de> Author: Armin Rigo Branch: stmgc-c4 Changeset: r67118:4b09d9d4ed36 Date: 2013-09-28 00:00 +0200 http://bitbucket.org/pypy/pypy/changeset/4b09d9d4ed36/ Log: Fix: need to correctly save the gcmap and restore the frame around this call 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 @@ -2897,9 +2897,10 @@ # call stm_transaction_break() with the address of the # STM_RESUME_BUF and the custom longjmp function mc.LEA_rs(edi.value, FRAME_FIXED_SIZE * WORD) - mc.MOV_ri(esi.value, self.stm_longjmp_callback_addr) fn = stmtlocal.stm_transaction_break_fn - mc.CALL(imm(self.cpu.cast_ptr_to_int(fn))) + self.simple_call(imm(self.cpu.cast_ptr_to_int(fn)), + [edi, imm(self.stm_longjmp_callback_addr)], + None) # # Fill the stm resume buffer. Don't do it before the call! # The previous transaction may still be aborted during the call From noreply at buildbot.pypy.org Sat Sep 28 00:17:56 2013 From: noreply at buildbot.pypy.org (arigo) Date: Sat, 28 Sep 2013 00:17:56 +0200 (CEST) Subject: [pypy-commit] pypy stmgc-c4: fix: 127 bytes is not enough here Message-ID: <20130927221756.84DD11C00EC@cobra.cs.uni-duesseldorf.de> Author: Armin Rigo Branch: stmgc-c4 Changeset: r67119:dd6c23b49a34 Date: 2013-09-28 00:13 +0200 http://bitbucket.org/pypy/pypy/changeset/dd6c23b49a34/ Log: fix: 127 bytes is not enough here 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 @@ -2891,7 +2891,7 @@ fn = stmtlocal.stm_should_break_transaction_fn mc.CALL(imm(self.cpu.cast_ptr_to_int(fn))) mc.TEST8(eax.lowest8bits(), eax.lowest8bits()) - mc.J_il8(rx86.Conditions['Z'], 0) + mc.J_il(rx86.Conditions['Z'], 0xfffff) # patched later jz_location = mc.get_relative_pos() # # call stm_transaction_break() with the address of the @@ -2917,8 +2917,7 @@ # # patch the JZ above offset = mc.get_relative_pos() - jz_location - assert 0 < offset <= 127 - mc.overwrite(jz_location-1, chr(offset)) + mc.overwrite32(jz_location-4, offset) genop_discard_list = [Assembler386.not_implemented_op_discard] * rop._LAST From noreply at buildbot.pypy.org Sat Sep 28 00:43:02 2013 From: noreply at buildbot.pypy.org (pjenvey) Date: Sat, 28 Sep 2013 00:43:02 +0200 (CEST) Subject: [pypy-commit] pypy py3k: merge default Message-ID: <20130927224302.01AC71C087E@cobra.cs.uni-duesseldorf.de> Author: Philip Jenvey Branch: py3k Changeset: r67120:c233a166c04b Date: 2013-09-27 15:27 -0700 http://bitbucket.org/pypy/pypy/changeset/c233a166c04b/ Log: merge default diff too long, truncating to 2000 out of 3595 lines diff --git a/lib-python/2.7/test/keycert.pem b/lib-python/2.7/test/keycert.pem --- a/lib-python/2.7/test/keycert.pem +++ b/lib-python/2.7/test/keycert.pem @@ -1,32 +1,31 @@ ------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 PRIVATE KEY----- +MIICdwIBADANBgkqhkiG9w0BAQEFAASCAmEwggJdAgEAAoGBANtb0+YrKuxevGpm +LrjaUhZSgz6zFAmuGFmKmUbdjmfv9zSmmdsQIksK++jK0Be9LeZy20j6ahOfuVa0 +ufEmPoP7Fy4hXegKZR9cCWcIe/A6H2xWF1IIJLRTLaU8ol/I7T+um5HD5AwAwNPP +USNU0Eegmvp+xxWu3NX2m1Veot85AgMBAAECgYA3ZdZ673X0oexFlq7AAmrutkHt +CL7LvwrpOiaBjhyTxTeSNWzvtQBkIU8DOI0bIazA4UreAFffwtvEuPmonDb3F+Iq +SMAu42XcGyVZEl+gHlTPU9XRX7nTOXVt+MlRRRxL6t9GkGfUAXI3XxJDXW3c0vBK +UL9xqD8cORXOfE06rQJBAP8mEX1ERkR64Ptsoe4281vjTlNfIbs7NMPkUnrn9N/Y +BLhjNIfQ3HFZG8BTMLfX7kCS9D593DW5tV4Z9BP/c6cCQQDcFzCcVArNh2JSywOQ +ZfTfRbJg/Z5Lt9Fkngv1meeGNPgIMLN8Sg679pAOOWmzdMO3V706rNPzSVMME7E5 +oPIfAkEA8pDddarP5tCvTTgUpmTFbakm0KoTZm2+FzHcnA4jRh+XNTjTOv98Y6Ik +eO5d1ZnKXseWvkZncQgxfdnMqqpj5wJAcNq/RVne1DbYlwWchT2Si65MYmmJ8t+F +0mcsULqjOnEMwf5e+ptq5LzwbyrHZYq5FNk7ocufPv/ZQrcSSC+cFwJBAKvOJByS +x56qyGeZLOQlWS2JS3KJo59XuLFGqcbgN9Om9xFa41Yb4N9NvplFivsvZdw3m1Q/ +SPIXQuT8RMPDVNQ= +-----END PRIVATE KEY----- -----BEGIN CERTIFICATE----- -MIICpzCCAhCgAwIBAgIJAP+qStv1cIGNMA0GCSqGSIb3DQEBBQUAMIGJMQswCQYD -VQQGEwJVUzERMA8GA1UECBMIRGVsYXdhcmUxEzARBgNVBAcTCldpbG1pbmd0b24x -IzAhBgNVBAoTGlB5dGhvbiBTb2Z0d2FyZSBGb3VuZGF0aW9uMQwwCgYDVQQLEwNT -U0wxHzAdBgNVBAMTFnNvbWVtYWNoaW5lLnB5dGhvbi5vcmcwHhcNMDcwODI3MTY1 -NDUwWhcNMTMwMjE2MTY1NDUwWjCBiTELMAkGA1UEBhMCVVMxETAPBgNVBAgTCERl -bGF3YXJlMRMwEQYDVQQHEwpXaWxtaW5ndG9uMSMwIQYDVQQKExpQeXRob24gU29m -dHdhcmUgRm91bmRhdGlvbjEMMAoGA1UECxMDU1NMMR8wHQYDVQQDExZzb21lbWFj -aGluZS5weXRob24ub3JnMIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQC8ddrh -m+LutBvjYcQlnH21PPIseJ1JVG2HMmN2CmZk2YukO+9LopdJhTvbGfEj0DQs1IE8 -M+kTUyOmuKfVrFMKwtVeCJphrAnhoz7TYOuLBSqt7lVHfhi/VwovESJlaBOp+WMn -fhcduPEYHYx/6cnVapIkZnLt30zu2um+DzA9jQIDAQABoxUwEzARBglghkgBhvhC -AQEEBAMCBkAwDQYJKoZIhvcNAQEFBQADgYEAF4Q5BVqmCOLv1n8je/Jw9K669VXb -08hyGzQhkemEBYQd6fzQ9A/1ZzHkJKb1P6yreOLSEh4KcxYPyrLRC1ll8nr5OlCx -CMhKkTnR6qBsdNV0XtdU2+N25hqW+Ma4ZeqsN/iiJVCGNOZGnvQuvCAGWF8+J/f/ -iHkC6gGdBJhogs4= +MIICVDCCAb2gAwIBAgIJANfHOBkZr8JOMA0GCSqGSIb3DQEBBQUAMF8xCzAJBgNV +BAYTAlhZMRcwFQYDVQQHEw5DYXN0bGUgQW50aHJheDEjMCEGA1UEChMaUHl0aG9u +IFNvZnR3YXJlIEZvdW5kYXRpb24xEjAQBgNVBAMTCWxvY2FsaG9zdDAeFw0xMDEw +MDgyMzAxNTZaFw0yMDEwMDUyMzAxNTZaMF8xCzAJBgNVBAYTAlhZMRcwFQYDVQQH +Ew5DYXN0bGUgQW50aHJheDEjMCEGA1UEChMaUHl0aG9uIFNvZnR3YXJlIEZvdW5k +YXRpb24xEjAQBgNVBAMTCWxvY2FsaG9zdDCBnzANBgkqhkiG9w0BAQEFAAOBjQAw +gYkCgYEA21vT5isq7F68amYuuNpSFlKDPrMUCa4YWYqZRt2OZ+/3NKaZ2xAiSwr7 +6MrQF70t5nLbSPpqE5+5VrS58SY+g/sXLiFd6AplH1wJZwh78DofbFYXUggktFMt +pTyiX8jtP66bkcPkDADA089RI1TQR6Ca+n7HFa7c1fabVV6i3zkCAwEAAaMYMBYw +FAYDVR0RBA0wC4IJbG9jYWxob3N0MA0GCSqGSIb3DQEBBQUAA4GBAHPctQBEQ4wd +BJ6+JcpIraopLn8BGhbjNWj40mmRqWB/NAWF6M5ne7KpGAu7tLeG4hb1zLaldK8G +lxy2GPSRF6LFS48dpEj2HbMv2nvv6xxalDMJ9+DicWgAKTQ6bcX2j3GUkCR0g/T1 +CRlNBAAlvhKzO7Clpf9l0YKBEfraJByX -----END CERTIFICATE----- diff --git a/lib-python/2.7/test/sha256.pem b/lib-python/2.7/test/sha256.pem --- a/lib-python/2.7/test/sha256.pem +++ b/lib-python/2.7/test/sha256.pem @@ -1,129 +1,128 @@ # Certificate chain for https://sha256.tbs-internet.com - 0 s:/C=FR/postalCode=14000/ST=Calvados/L=CAEN/street=22 rue de Bretagne/O=TBS INTERNET/OU=0002 440443810/OU=sha-256 production/CN=sha256.tbs-internet.com - i:/C=FR/ST=Calvados/L=Caen/O=TBS INTERNET/OU=Terms and Conditions: http://www.tbs-internet.com/CA/repository/OU=TBS INTERNET CA/CN=TBS X509 CA SGC + 0 s:/C=FR/postalCode=14000/ST=Calvados/L=CAEN/street=22 rue de Bretagne/O=TBS INTERNET/OU=0002 440443810/OU=Certificats TBS X509/CN=ecom.tbs-x509.com + i:/C=FR/ST=Calvados/L=Caen/O=TBS INTERNET/OU=Terms and Conditions: http://www.tbs-internet.com/CA/repository/OU=TBS INTERNET CA/CN=TBS X509 CA business -----BEGIN CERTIFICATE----- -MIIGXTCCBUWgAwIBAgIRAMmag+ygSAdxZsbyzYjhuW0wDQYJKoZIhvcNAQELBQAw -gcQxCzAJBgNVBAYTAkZSMREwDwYDVQQIEwhDYWx2YWRvczENMAsGA1UEBxMEQ2Fl +MIIGTjCCBTagAwIBAgIQOh3d9dNDPq1cSdJmEiMpqDANBgkqhkiG9w0BAQUFADCB +yTELMAkGA1UEBhMCRlIxETAPBgNVBAgTCENhbHZhZG9zMQ0wCwYDVQQHEwRDYWVu +MRUwEwYDVQQKEwxUQlMgSU5URVJORVQxSDBGBgNVBAsTP1Rlcm1zIGFuZCBDb25k +aXRpb25zOiBodHRwOi8vd3d3LnRicy1pbnRlcm5ldC5jb20vQ0EvcmVwb3NpdG9y +eTEYMBYGA1UECxMPVEJTIElOVEVSTkVUIENBMR0wGwYDVQQDExRUQlMgWDUwOSBD +QSBidXNpbmVzczAeFw0xMTAxMjUwMDAwMDBaFw0xMzAyMDUyMzU5NTlaMIHHMQsw +CQYDVQQGEwJGUjEOMAwGA1UEERMFMTQwMDAxETAPBgNVBAgTCENhbHZhZG9zMQ0w +CwYDVQQHEwRDQUVOMRswGQYDVQQJExIyMiBydWUgZGUgQnJldGFnbmUxFTATBgNV +BAoTDFRCUyBJTlRFUk5FVDEXMBUGA1UECxMOMDAwMiA0NDA0NDM4MTAxHTAbBgNV +BAsTFENlcnRpZmljYXRzIFRCUyBYNTA5MRowGAYDVQQDExFlY29tLnRicy14NTA5 +LmNvbTCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBAKRrlHUnJ++1lpcg +jtYco7cdmRe+EEfTmwPfCdfV3G1QfsTSvY6FfMpm/83pqHfT+4ANwr18wD9ZrAEN +G16mf9VdCGK12+TP7DmqeZyGIqlFFoahQnmb8EarvE43/1UeQ2CV9XmzwZvpqeli +LfXsFonawrY3H6ZnMwS64St61Z+9gdyuZ/RbsoZBbT5KUjDEG844QRU4OT1IGeEI +eY5NM5RNIh6ZNhVtqeeCxMS7afONkHQrOco73RdSTRck/Hj96Ofl3MHNHryr+AMK +DGFk1kLCZGpPdXtkxXvaDeQoiYDlil26CWc+YK6xyDPMdsWvoG14ZLyCpzMXA7/7 +4YAQRH0CAwEAAaOCAjAwggIsMB8GA1UdIwQYMBaAFBoJBMz5CY+7HqDO1KQUf0vV +I1jNMB0GA1UdDgQWBBQgOU8HsWzbmD4WZP5Wtdw7jca2WDAOBgNVHQ8BAf8EBAMC +BaAwDAYDVR0TAQH/BAIwADAdBgNVHSUEFjAUBggrBgEFBQcDAQYIKwYBBQUHAwIw +TAYDVR0gBEUwQzBBBgsrBgEEAYDlNwIBATAyMDAGCCsGAQUFBwIBFiRodHRwczov +L3d3dy50YnMtaW50ZXJuZXQuY29tL0NBL0NQUzEwdwYDVR0fBHAwbjA3oDWgM4Yx +aHR0cDovL2NybC50YnMtaW50ZXJuZXQuY29tL1RCU1g1MDlDQWJ1c2luZXNzLmNy +bDAzoDGgL4YtaHR0cDovL2NybC50YnMteDUwOS5jb20vVEJTWDUwOUNBYnVzaW5l +c3MuY3JsMIGwBggrBgEFBQcBAQSBozCBoDA9BggrBgEFBQcwAoYxaHR0cDovL2Ny +dC50YnMtaW50ZXJuZXQuY29tL1RCU1g1MDlDQWJ1c2luZXNzLmNydDA5BggrBgEF +BQcwAoYtaHR0cDovL2NydC50YnMteDUwOS5jb20vVEJTWDUwOUNBYnVzaW5lc3Mu +Y3J0MCQGCCsGAQUFBzABhhhodHRwOi8vb2NzcC50YnMteDUwOS5jb20wMwYDVR0R +BCwwKoIRZWNvbS50YnMteDUwOS5jb22CFXd3dy5lY29tLnRicy14NTA5LmNvbTAN +BgkqhkiG9w0BAQUFAAOCAQEArT4NHfbY87bGAw8lPV4DmHlmuDuVp/y7ltO3Ynse +3Rz8RxW2AzuO0Oy2F0Cu4yWKtMyEyMXyHqWtae7ElRbdTu5w5GwVBLJHClCzC8S9 +SpgMMQTx3Rgn8vjkHuU9VZQlulZyiPK7yunjc7c310S9FRZ7XxOwf8Nnx4WnB+No +WrfApzhhQl31w+RyrNxZe58hCfDDHmevRvwLjQ785ZoQXJDj2j3qAD4aI2yB8lB5 +oaE1jlCJzC7Kmz/Y9jzfmv/zAs1LQTm9ktevv4BTUFaGjv9jxnQ1xnS862ZiouLW +zZYIlYPf4F6JjXGiIQgQRglILUfq3ftJd9/ok9W9ZF8h8w== +-----END CERTIFICATE----- + 1 s:/C=FR/ST=Calvados/L=Caen/O=TBS INTERNET/OU=Terms and Conditions: http://www.tbs-internet.com/CA/repository/OU=TBS INTERNET CA/CN=TBS X509 CA business + i:/C=SE/O=AddTrust AB/OU=AddTrust External TTP Network/CN=AddTrust External CA Root +-----BEGIN CERTIFICATE----- +MIIFPzCCBCegAwIBAgIQDlBz/++iRSmLDeVRHT/hADANBgkqhkiG9w0BAQUFADBv +MQswCQYDVQQGEwJTRTEUMBIGA1UEChMLQWRkVHJ1c3QgQUIxJjAkBgNVBAsTHUFk +ZFRydXN0IEV4dGVybmFsIFRUUCBOZXR3b3JrMSIwIAYDVQQDExlBZGRUcnVzdCBF +eHRlcm5hbCBDQSBSb290MB4XDTA1MTIwMTAwMDAwMFoXDTE5MDcwOTE4MTkyMlow +gckxCzAJBgNVBAYTAkZSMREwDwYDVQQIEwhDYWx2YWRvczENMAsGA1UEBxMEQ2Fl bjEVMBMGA1UEChMMVEJTIElOVEVSTkVUMUgwRgYDVQQLEz9UZXJtcyBhbmQgQ29u ZGl0aW9uczogaHR0cDovL3d3dy50YnMtaW50ZXJuZXQuY29tL0NBL3JlcG9zaXRv -cnkxGDAWBgNVBAsTD1RCUyBJTlRFUk5FVCBDQTEYMBYGA1UEAxMPVEJTIFg1MDkg -Q0EgU0dDMB4XDTEwMDIxODAwMDAwMFoXDTEyMDIxOTIzNTk1OVowgcsxCzAJBgNV -BAYTAkZSMQ4wDAYDVQQREwUxNDAwMDERMA8GA1UECBMIQ2FsdmFkb3MxDTALBgNV -BAcTBENBRU4xGzAZBgNVBAkTEjIyIHJ1ZSBkZSBCcmV0YWduZTEVMBMGA1UEChMM -VEJTIElOVEVSTkVUMRcwFQYDVQQLEw4wMDAyIDQ0MDQ0MzgxMDEbMBkGA1UECxMS -c2hhLTI1NiBwcm9kdWN0aW9uMSAwHgYDVQQDExdzaGEyNTYudGJzLWludGVybmV0 -LmNvbTCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBAKbuM8VT7f0nntwu -N3F7v9KIBlhKNAxqCrziOXU5iqUt8HrQB3DtHbdmII+CpVUlwlmepsx6G+srEZ9a -MIGAy0nxi5aLb7watkyIdPjJTMvTUBQ/+RPWzt5JtYbbY9BlJ+yci0dctP74f4NU -ISLtlrEjUbf2gTohLrcE01TfmOF6PDEbB5PKDi38cB3NzKfizWfrOaJW6Q1C1qOJ -y4/4jkUREX1UFUIxzx7v62VfjXSGlcjGpBX1fvtABQOSLeE0a6gciDZs1REqroFf -5eXtqYphpTa14Z83ITXMfgg5Nze1VtMnzI9Qx4blYBw4dgQVEuIsYr7FDBOITDzc -VEVXZx0CAwEAAaOCAj8wggI7MB8GA1UdIwQYMBaAFAdEdoWTKLx/bXjSCuv6TEvf -2YIfMB0GA1UdDgQWBBSJKI/AYVI9RQNY0QPIqc8ej2QivTAOBgNVHQ8BAf8EBAMC -BaAwDAYDVR0TAQH/BAIwADA0BgNVHSUELTArBggrBgEFBQcDAQYIKwYBBQUHAwIG -CisGAQQBgjcKAwMGCWCGSAGG+EIEATBMBgNVHSAERTBDMEEGCysGAQQBgOU3AgQB -MDIwMAYIKwYBBQUHAgEWJGh0dHBzOi8vd3d3LnRicy1pbnRlcm5ldC5jb20vQ0Ev -Q1BTNDBtBgNVHR8EZjBkMDKgMKAuhixodHRwOi8vY3JsLnRicy1pbnRlcm5ldC5j -b20vVEJTWDUwOUNBU0dDLmNybDAuoCygKoYoaHR0cDovL2NybC50YnMteDUwOS5j -b20vVEJTWDUwOUNBU0dDLmNybDCBpgYIKwYBBQUHAQEEgZkwgZYwOAYIKwYBBQUH -MAKGLGh0dHA6Ly9jcnQudGJzLWludGVybmV0LmNvbS9UQlNYNTA5Q0FTR0MuY3J0 -MDQGCCsGAQUFBzAChihodHRwOi8vY3J0LnRicy14NTA5LmNvbS9UQlNYNTA5Q0FT -R0MuY3J0MCQGCCsGAQUFBzABhhhodHRwOi8vb2NzcC50YnMteDUwOS5jb20wPwYD -VR0RBDgwNoIXc2hhMjU2LnRicy1pbnRlcm5ldC5jb22CG3d3dy5zaGEyNTYudGJz -LWludGVybmV0LmNvbTANBgkqhkiG9w0BAQsFAAOCAQEAA5NL0D4QSqhErhlkdPmz -XtiMvdGL+ZehM4coTRIpasM/Agt36Rc0NzCvnQwKE+wkngg1Gy2qe7Q0E/ziqBtB -fZYzdVgu1zdiL4kTaf+wFKYAFGsFbyeEmXysy+CMwaNoF2vpSjCU1UD56bEnTX/W -fxVZYxtBQUpnu2wOsm8cDZuZRv9XrYgAhGj9Tt6F0aVHSDGn59uwShG1+BVF/uju -SCyPTTjL1oc7YElJUzR/x4mQJYvtQI8gDIDAGEOs7v3R/gKa5EMfbUQUI4C84UbI -Yz09Jdnws/MkC/Hm1BZEqk89u7Hvfv+oHqEb0XaUo0TDfsxE0M1sMdnLb91QNQBm -UQ== ------END CERTIFICATE----- - 1 s:/C=FR/ST=Calvados/L=Caen/O=TBS INTERNET/OU=Terms and Conditions: http://www.tbs-internet.com/CA/repository/OU=TBS INTERNET CA/CN=TBS X509 CA SGC - i:/C=SE/O=AddTrust AB/OU=AddTrust External TTP Network/CN=AddTrust External CA Root ------BEGIN CERTIFICATE----- -MIIFVjCCBD6gAwIBAgIQXpDZ0ETJMV02WTx3GTnhhTANBgkqhkiG9w0BAQUFADBv -MQswCQYDVQQGEwJTRTEUMBIGA1UEChMLQWRkVHJ1c3QgQUIxJjAkBgNVBAsTHUFk -ZFRydXN0IEV4dGVybmFsIFRUUCBOZXR3b3JrMSIwIAYDVQQDExlBZGRUcnVzdCBF -eHRlcm5hbCBDQSBSb290MB4XDTA1MTIwMTAwMDAwMFoXDTE5MDYyNDE5MDYzMFow -gcQxCzAJBgNVBAYTAkZSMREwDwYDVQQIEwhDYWx2YWRvczENMAsGA1UEBxMEQ2Fl -bjEVMBMGA1UEChMMVEJTIElOVEVSTkVUMUgwRgYDVQQLEz9UZXJtcyBhbmQgQ29u -ZGl0aW9uczogaHR0cDovL3d3dy50YnMtaW50ZXJuZXQuY29tL0NBL3JlcG9zaXRv -cnkxGDAWBgNVBAsTD1RCUyBJTlRFUk5FVCBDQTEYMBYGA1UEAxMPVEJTIFg1MDkg -Q0EgU0dDMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAsgOkO3f7wzN6 -rOjg45tR5vjBfzK7qmV9IBxb/QW9EEXxG+E7FNhZqQLtwGBKoSsHTnQqV75wWMk0 -9tinWvftBkSpj5sTi/8cbzJfUvTSVYh3Qxv6AVVjMMH/ruLjE6y+4PoaPs8WoYAQ -ts5R4Z1g8c/WnTepLst2x0/Wv7GmuoQi+gXvHU6YrBiu7XkeYhzc95QdviWSJRDk -owhb5K43qhcvjRmBfO/paGlCliDGZp8mHwrI21mwobWpVjTxZRwYO3bd4+TGcI4G -Ie5wmHwE8F7SK1tgSqbBacKjDa93j7txKkfz/Yd2n7TGqOXiHPsJpG655vrKtnXk -9vs1zoDeJQIDAQABo4IBljCCAZIwHQYDVR0OBBYEFAdEdoWTKLx/bXjSCuv6TEvf -2YIfMA4GA1UdDwEB/wQEAwIBBjASBgNVHRMBAf8ECDAGAQH/AgEAMCAGA1UdJQQZ -MBcGCisGAQQBgjcKAwMGCWCGSAGG+EIEATAYBgNVHSAEETAPMA0GCysGAQQBgOU3 -AgQBMHsGA1UdHwR0MHIwOKA2oDSGMmh0dHA6Ly9jcmwuY29tb2RvY2EuY29tL0Fk -ZFRydXN0RXh0ZXJuYWxDQVJvb3QuY3JsMDagNKAyhjBodHRwOi8vY3JsLmNvbW9k -by5uZXQvQWRkVHJ1c3RFeHRlcm5hbENBUm9vdC5jcmwwgYAGCCsGAQUFBwEBBHQw -cjA4BggrBgEFBQcwAoYsaHR0cDovL2NydC5jb21vZG9jYS5jb20vQWRkVHJ1c3RV -VE5TR0NDQS5jcnQwNgYIKwYBBQUHMAKGKmh0dHA6Ly9jcnQuY29tb2RvLm5ldC9B -ZGRUcnVzdFVUTlNHQ0NBLmNydDARBglghkgBhvhCAQEEBAMCAgQwDQYJKoZIhvcN -AQEFBQADggEBAK2zEzs+jcIrVK9oDkdDZNvhuBYTdCfpxfFs+OAujW0bIfJAy232 -euVsnJm6u/+OrqKudD2tad2BbejLLXhMZViaCmK7D9nrXHx4te5EP8rL19SUVqLY -1pTnv5dhNgEgvA7n5lIzDSYs7yRLsr7HJsYPr6SeYSuZizyX1SNz7ooJ32/F3X98 -RB0Mlc/E0OyOrkQ9/y5IrnpnaSora8CnUrV5XNOg+kyCz9edCyx4D5wXYcwZPVWz -8aDqquESrezPyjtfi4WRO4s/VD3HLZvOxzMrWAVYCDG9FxaOhF0QGuuG1F7F3GKV -v6prNyCl016kRl2j1UT+a7gLd8fA25A4C9E= +cnkxGDAWBgNVBAsTD1RCUyBJTlRFUk5FVCBDQTEdMBsGA1UEAxMUVEJTIFg1MDkg +Q0EgYnVzaW5lc3MwggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQDB1PAU +qudCcz3tmyGcf+u6EkZqonKKHrV4gZYbvVkIRojmmlhfi/jwvpHvo8bqSt/9Rj5S +jhCDW0pcbI+IPPtD1Jy+CHNSfnMqVDy6CKQ3p5maTzCMG6ZT+XjnvcND5v+FtaiB +xk1iCX6uvt0jeUtdZvYbyytsSDE6c3Y5//wRxOF8tM1JxibwO3pyER26jbbN2gQz +m/EkdGjLdJ4svPk23WDAvQ6G0/z2LcAaJB+XLfqRwfQpHQvfKa1uTi8PivC8qtip +rmNQMMPMjxSK2azX8cKjjTDJiUKaCb4VHlJDWKEsCFRpgJAoAuX8f7Yfs1M4esGo +sWb3PGspK3O22uIlAgMBAAGjggF6MIIBdjAdBgNVHQ4EFgQUGgkEzPkJj7seoM7U +pBR/S9UjWM0wDgYDVR0PAQH/BAQDAgEGMBIGA1UdEwEB/wQIMAYBAf8CAQAwGAYD +VR0gBBEwDzANBgsrBgEEAYDlNwIBATB7BgNVHR8EdDByMDigNqA0hjJodHRwOi8v +Y3JsLmNvbW9kb2NhLmNvbS9BZGRUcnVzdEV4dGVybmFsQ0FSb290LmNybDA2oDSg +MoYwaHR0cDovL2NybC5jb21vZG8ubmV0L0FkZFRydXN0RXh0ZXJuYWxDQVJvb3Qu +Y3JsMIGGBggrBgEFBQcBAQR6MHgwOwYIKwYBBQUHMAKGL2h0dHA6Ly9jcnQuY29t +b2RvY2EuY29tL0FkZFRydXN0VVROU2VydmVyQ0EuY3J0MDkGCCsGAQUFBzAChi1o +dHRwOi8vY3J0LmNvbW9kby5uZXQvQWRkVHJ1c3RVVE5TZXJ2ZXJDQS5jcnQwEQYJ +YIZIAYb4QgEBBAQDAgIEMA0GCSqGSIb3DQEBBQUAA4IBAQA7mqrMgk/MrE6QnbNA +h4nRCn2ti4bg4w2C3lB6bSvRPnYwuNw9Jb8vuKkNFzRDxNJXqVDZdfFW5CVQJuyd +nfAx83+wk+spzvFaE1KhFYfN9G9pQfXUfvDRoIcJgPEKUXL1wRiOG+IjU3VVI8pg +IgqHkr7ylln5i5zCiFAPuIJmYUSFg/gxH5xkCNcjJqqrHrHatJr6Qrrke93joupw +oU1njfAcZtYp6fbiK6u2b1pJqwkVBE8RsfLnPhRj+SFbpvjv8Od7o/ieJhFIYQNU +k2jX2u8qZnAiNw93LZW9lpYjtuvMXq8QQppENNja5b53q7UwI+lU7ZGjZ7quuESp +J6/5 -----END CERTIFICATE----- 2 s:/C=SE/O=AddTrust AB/OU=AddTrust External TTP Network/CN=AddTrust External CA Root - i:/C=US/ST=UT/L=Salt Lake City/O=The USERTRUST Network/OU=http://www.usertrust.com/CN=UTN - DATACorp SGC + i:/C=US/ST=UT/L=Salt Lake City/O=The USERTRUST Network/OU=http://www.usertrust.com/CN=UTN-USERFirst-Hardware -----BEGIN CERTIFICATE----- -MIIEZjCCA06gAwIBAgIQUSYKkxzif5zDpV954HKugjANBgkqhkiG9w0BAQUFADCB -kzELMAkGA1UEBhMCVVMxCzAJBgNVBAgTAlVUMRcwFQYDVQQHEw5TYWx0IExha2Ug +MIIETzCCAzegAwIBAgIQHM5EYpUZep1jUvnyI6m2mDANBgkqhkiG9w0BAQUFADCB +lzELMAkGA1UEBhMCVVMxCzAJBgNVBAgTAlVUMRcwFQYDVQQHEw5TYWx0IExha2Ug Q2l0eTEeMBwGA1UEChMVVGhlIFVTRVJUUlVTVCBOZXR3b3JrMSEwHwYDVQQLExho -dHRwOi8vd3d3LnVzZXJ0cnVzdC5jb20xGzAZBgNVBAMTElVUTiAtIERBVEFDb3Jw -IFNHQzAeFw0wNTA2MDcwODA5MTBaFw0xOTA2MjQxOTA2MzBaMG8xCzAJBgNVBAYT -AlNFMRQwEgYDVQQKEwtBZGRUcnVzdCBBQjEmMCQGA1UECxMdQWRkVHJ1c3QgRXh0 -ZXJuYWwgVFRQIE5ldHdvcmsxIjAgBgNVBAMTGUFkZFRydXN0IEV4dGVybmFsIENB -IFJvb3QwggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQC39xoz5vIABC05 -4E5b7R+8bA/Ntfojts7emxEzl6QpTH2Tn71KvJPtAxrjj8/lbVBa1pcplFqAsEl6 -2y6V/bjKvzc4LR4+kUGtcFbH8E8/6DKedMrIkFTpxl8PeJ2aQDwOrGGqXhSPnoeh -alDc15pOrwWzpnGUnHGzUGAKxxOdOAeGAqjpqGkmGJCrTLBPI6s6T4TY386f4Wlv -u9dC12tE5Met7m1BX3JacQg3s3llpFmglDf3AC8NwpJy2tA4ctsUqEXEXSp9t7TW -xO6szRNEt8kr3UMAJfphuWlqWCMRt6czj1Z1WfXNKddGtworZbbTQm8Vsrh7++/p -XVPVNFonAgMBAAGjgdgwgdUwHwYDVR0jBBgwFoAUUzLRs89/+uDxoF2FTpLSnkUd -tE8wHQYDVR0OBBYEFK29mHo0tCb3+sQmVO8DveAky1QaMA4GA1UdDwEB/wQEAwIB -BjAPBgNVHRMBAf8EBTADAQH/MBEGCWCGSAGG+EIBAQQEAwIBAjAgBgNVHSUEGTAX -BgorBgEEAYI3CgMDBglghkgBhvhCBAEwPQYDVR0fBDYwNDAyoDCgLoYsaHR0cDov -L2NybC51c2VydHJ1c3QuY29tL1VUTi1EQVRBQ29ycFNHQy5jcmwwDQYJKoZIhvcN -AQEFBQADggEBAMbuUxdoFLJRIh6QWA2U/b3xcOWGLcM2MY9USEbnLQg3vGwKYOEO -rVE04BKT6b64q7gmtOmWPSiPrmQH/uAB7MXjkesYoPF1ftsK5p+R26+udd8jkWjd -FwBaS/9kbHDrARrQkNnHptZt9hPk/7XJ0h4qy7ElQyZ42TCbTg0evmnv3+r+LbPM -+bDdtRTKkdSytaX7ARmjR3mfnYyVhzT4HziS2jamEfpr62vp3EV4FTkG101B5CHI -3C+H0be/SGB1pWLLJN47YaApIKa+xWycxOkKaSLvkTr6Jq/RW0GnOuL4OAdCq8Fb -+M5tug8EPzI0rNwEKNdwMBQmBsTkm5jVz3g= +dHRwOi8vd3d3LnVzZXJ0cnVzdC5jb20xHzAdBgNVBAMTFlVUTi1VU0VSRmlyc3Qt +SGFyZHdhcmUwHhcNMDUwNjA3MDgwOTEwWhcNMTkwNzA5MTgxOTIyWjBvMQswCQYD +VQQGEwJTRTEUMBIGA1UEChMLQWRkVHJ1c3QgQUIxJjAkBgNVBAsTHUFkZFRydXN0 +IEV4dGVybmFsIFRUUCBOZXR3b3JrMSIwIAYDVQQDExlBZGRUcnVzdCBFeHRlcm5h +bCBDQSBSb290MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAt/caM+by +AAQtOeBOW+0fvGwPzbX6I7bO3psRM5ekKUx9k5+9SryT7QMa44/P5W1QWtaXKZRa +gLBJetsulf24yr83OC0ePpFBrXBWx/BPP+gynnTKyJBU6cZfD3idmkA8Dqxhql4U +j56HoWpQ3NeaTq8Fs6ZxlJxxs1BgCscTnTgHhgKo6ahpJhiQq0ywTyOrOk+E2N/O +n+Fpb7vXQtdrROTHre5tQV9yWnEIN7N5ZaRZoJQ39wAvDcKSctrQOHLbFKhFxF0q +fbe01sTurM0TRLfJK91DACX6YblpalgjEbenM49WdVn1zSnXRrcKK2W200JvFbK4 +e/vv6V1T1TRaJwIDAQABo4G9MIG6MB8GA1UdIwQYMBaAFKFyXyYbKJhDlV0HN9WF +lp1L0sNFMB0GA1UdDgQWBBStvZh6NLQm9/rEJlTvA73gJMtUGjAOBgNVHQ8BAf8E +BAMCAQYwDwYDVR0TAQH/BAUwAwEB/zARBglghkgBhvhCAQEEBAMCAQIwRAYDVR0f +BD0wOzA5oDegNYYzaHR0cDovL2NybC51c2VydHJ1c3QuY29tL1VUTi1VU0VSRmly +c3QtSGFyZHdhcmUuY3JsMA0GCSqGSIb3DQEBBQUAA4IBAQByQhANOs4kClrwF8BW +onvUOGCSjRK52zYZgDXYNjDtmr5rJ6NyPFDNn+JxkLpjYetIFMTbSRe679Bt8m7a +gIAoQYFQtxMuyLnJegB2aEbQiIxh/tC21UcFF7ktdnDoTlA6w3pLuvunaI84Of3o +2YBrhzkTbCfaYk5JRlTpudW9DkUkHBsyx3nknPKnplkIGaK0jgn8E0n+SFabYaHk +I9LroYT/+JtLefh9lgBdAgVv0UPbzoGfuDsrk/Zh+UrgbLFpHoVnElhzbkh64Z0X +OGaJunQc68cCZu5HTn/aK7fBGMcVflRCXLVEQpU9PIAdGA8Ynvg684t8GMaKsRl1 +jIGZ -----END CERTIFICATE----- - 3 s:/C=US/ST=UT/L=Salt Lake City/O=The USERTRUST Network/OU=http://www.usertrust.com/CN=UTN - DATACorp SGC - i:/C=US/ST=UT/L=Salt Lake City/O=The USERTRUST Network/OU=http://www.usertrust.com/CN=UTN - DATACorp SGC + 3 s:/C=US/ST=UT/L=Salt Lake City/O=The USERTRUST Network/OU=http://www.usertrust.com/CN=UTN-USERFirst-Hardware + i:/C=US/ST=UT/L=Salt Lake City/O=The USERTRUST Network/OU=http://www.usertrust.com/CN=UTN-USERFirst-Hardware -----BEGIN CERTIFICATE----- -MIIEXjCCA0agAwIBAgIQRL4Mi1AAIbQR0ypoBqmtaTANBgkqhkiG9w0BAQUFADCB -kzELMAkGA1UEBhMCVVMxCzAJBgNVBAgTAlVUMRcwFQYDVQQHEw5TYWx0IExha2Ug +MIIEdDCCA1ygAwIBAgIQRL4Mi1AAJLQR0zYq/mUK/TANBgkqhkiG9w0BAQUFADCB +lzELMAkGA1UEBhMCVVMxCzAJBgNVBAgTAlVUMRcwFQYDVQQHEw5TYWx0IExha2Ug Q2l0eTEeMBwGA1UEChMVVGhlIFVTRVJUUlVTVCBOZXR3b3JrMSEwHwYDVQQLExho -dHRwOi8vd3d3LnVzZXJ0cnVzdC5jb20xGzAZBgNVBAMTElVUTiAtIERBVEFDb3Jw -IFNHQzAeFw05OTA2MjQxODU3MjFaFw0xOTA2MjQxOTA2MzBaMIGTMQswCQYDVQQG -EwJVUzELMAkGA1UECBMCVVQxFzAVBgNVBAcTDlNhbHQgTGFrZSBDaXR5MR4wHAYD -VQQKExVUaGUgVVNFUlRSVVNUIE5ldHdvcmsxITAfBgNVBAsTGGh0dHA6Ly93d3cu -dXNlcnRydXN0LmNvbTEbMBkGA1UEAxMSVVROIC0gREFUQUNvcnAgU0dDMIIBIjAN -BgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEA3+5YEKIrblXEjr8uRgnn4AgPLit6 -E5Qbvfa2gI5lBZMAHryv4g+OGQ0SR+ysraP6LnD43m77VkIVni5c7yPeIbkFdicZ -D0/Ww5y0vpQZY/KmEQrrU0icvvIpOxboGqBMpsn0GFlowHDyUwDAXlCCpVZvNvlK -4ESGoE1O1kduSUrLZ9emxAW5jh70/P/N5zbgnAVssjMiFdC04MwXwLLA9P4yPykq -lXvY8qdOD1R8oQ2AswkDwf9c3V6aPryuvEeKaq5xyh+xKrhfQgUL7EYw0XILyulW -bfXv33i+Ybqypa4ETLyorGkVl73v67SMvzX41MPRKA5cOp9wGDMgd8SirwIDAQAB -o4GrMIGoMAsGA1UdDwQEAwIBxjAPBgNVHRMBAf8EBTADAQH/MB0GA1UdDgQWBBRT -MtGzz3/64PGgXYVOktKeRR20TzA9BgNVHR8ENjA0MDKgMKAuhixodHRwOi8vY3Js -LnVzZXJ0cnVzdC5jb20vVVROLURBVEFDb3JwU0dDLmNybDAqBgNVHSUEIzAhBggr -BgEFBQcDAQYKKwYBBAGCNwoDAwYJYIZIAYb4QgQBMA0GCSqGSIb3DQEBBQUAA4IB -AQAnNZcAiosovcYzMB4p/OL31ZjUQLtgyr+rFywJNn9Q+kHcrpY6CiM+iVnJowft -Gzet/Hy+UUla3joKVAgWRcKZsYfNjGjgaQPpxE6YsjuMFrMOoAyYUJuTqXAJyCyj -j98C5OBxOvG0I3KgqgHf35g+FFCgMSa9KOlaMCZ1+XtgHI3zzVAmbQQnmt/VDUVH -KWss5nbZqSl9Mt3JNjy9rjXxEZ4du5A/EkdOjtd+D2JzHVImOBwYSf0wdJrE5SIv -2MCN7ZF6TACPcn9d2t0bi0Vr591pl6jFVkwPDPafepE39peC4N1xaf92P2BNPM/3 -mfnGV/TJVTl4uix5yaaIK/QI +dHRwOi8vd3d3LnVzZXJ0cnVzdC5jb20xHzAdBgNVBAMTFlVUTi1VU0VSRmlyc3Qt +SGFyZHdhcmUwHhcNOTkwNzA5MTgxMDQyWhcNMTkwNzA5MTgxOTIyWjCBlzELMAkG +A1UEBhMCVVMxCzAJBgNVBAgTAlVUMRcwFQYDVQQHEw5TYWx0IExha2UgQ2l0eTEe +MBwGA1UEChMVVGhlIFVTRVJUUlVTVCBOZXR3b3JrMSEwHwYDVQQLExhodHRwOi8v +d3d3LnVzZXJ0cnVzdC5jb20xHzAdBgNVBAMTFlVUTi1VU0VSRmlyc3QtSGFyZHdh +cmUwggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQCx98M4P7Sof885glFn +0G2f0v9Y8+efK+wNiVSZuTiZFvfgIXlIwrthdBKWHTxqctU8EGc6Oe0rE81m65UJ +M6Rsl7HoxuzBdXmcRl6Nq9Bq/bkqVRcQVLMZ8Jr28bFdtqdt++BxF2uiiPsA3/4a +MXcMmgF6sTLjKwEHOG7DpV4jvEWbe1DByTCP2+UretNb+zNAHqDVmBe8i4fDidNd +oI6yqqr2jmmIBsX6iSHzCJ1pLgkzmykNRg+MzEk0sGlRvfkGzWitZky8PqxhvQqI +DsjfPe58BEydCl5rkdbux+0ojatNh4lz0G6k0B4WixThdkQDf2Os5M1JnMWS9Ksy +oUhbAgMBAAGjgbkwgbYwCwYDVR0PBAQDAgHGMA8GA1UdEwEB/wQFMAMBAf8wHQYD +VR0OBBYEFKFyXyYbKJhDlV0HN9WFlp1L0sNFMEQGA1UdHwQ9MDswOaA3oDWGM2h0 +dHA6Ly9jcmwudXNlcnRydXN0LmNvbS9VVE4tVVNFUkZpcnN0LUhhcmR3YXJlLmNy +bDAxBgNVHSUEKjAoBggrBgEFBQcDAQYIKwYBBQUHAwUGCCsGAQUFBwMGBggrBgEF +BQcDBzANBgkqhkiG9w0BAQUFAAOCAQEARxkP3nTGmZev/K0oXnWO6y1n7k57K9cM +//bey1WiCuFMVGWTYGufEpytXoMs61quwOQt9ABjHbjAbPLPSbtNk28Gpgoiskli +CE7/yMgUsogWXecB5BKV5UU0s4tpvc+0hY91UZ59Ojg6FEgSxvunOxqNDYJAB+gE +CJChicsZUN/KHAG8HQQZexB2lzvukJDKxA4fFm517zP4029bHpbj4HR3dHuKom4t +3XbWOTCC8KucUvIqx69JXn7HaOWCgchqJ/kniCrVWFCVH/A7HFe7fRQ5YiuayZSS +KqMiDP+JJn1fIytH1xUdqWqeUQ0qUZ6B+dQ7XnASfxAynB67nfhmqA== -----END CERTIFICATE----- diff --git a/lib-python/2.7/test/test_ssl.py b/lib-python/2.7/test/test_ssl.py --- a/lib-python/2.7/test/test_ssl.py +++ b/lib-python/2.7/test/test_ssl.py @@ -111,13 +111,12 @@ if test_support.verbose: sys.stdout.write("\n" + pprint.pformat(p) + "\n") self.assertEqual(p['subject'], - ((('countryName', u'US'),), - (('stateOrProvinceName', u'Delaware'),), - (('localityName', u'Wilmington'),), - (('organizationName', u'Python Software Foundation'),), - (('organizationalUnitName', u'SSL'),), - (('commonName', u'somemachine.python.org'),)), + ((('countryName', 'XY'),), + (('localityName', 'Castle Anthrax'),), + (('organizationName', 'Python Software Foundation'),), + (('commonName', 'localhost'),)) ) + self.assertEqual(p['subjectAltName'], (('DNS', 'localhost'),)) # Issue #13034: the subjectAltName in some certificates # (notably projects.developer.nokia.com:443) wasn't parsed p = ssl._ssl._test_decode_cert(NOKIACERT) diff --git a/lib_pypy/numpy.py b/lib_pypy/numpy.py --- a/lib_pypy/numpy.py +++ b/lib_pypy/numpy.py @@ -1,5 +1,12 @@ -raise ImportError( - "The 'numpy' module of PyPy is in-development and not complete. " - "To try it out anyway, you can either import from 'numpypy', " - "or just write 'import numpypy' first in your program and then " - "import from 'numpy' as usual.") +import warnings +import sys +if 'numpypy' not in sys.modules: + warnings.warn( + "The 'numpy' module of PyPy is in-development and not complete. " + "To avoid this warning, write 'import numpypy as numpy'. ", + UserWarning) # XXX is this the best warning type? + +from numpypy import * +import numpypy +__all__ = numpypy.__all__ +del numpypy diff --git a/lib_pypy/numpypy/__init__.py b/lib_pypy/numpypy/__init__.py --- a/lib_pypy/numpypy/__init__.py +++ b/lib_pypy/numpypy/__init__.py @@ -6,9 +6,19 @@ from __builtin__ import bool, int, long, float, complex, object, unicode, str from core import abs, max, min -__all__ = [] +__version__ = '1.7.0' + +import os +def get_include(): + head, tail = os.path.split(os.path.dirname(os.path.abspath(__file__))) + return os.path.join(head, '../include') + + +__all__ = ['__version__', 'get_include'] __all__ += core.__all__ __all__ += lib.__all__ -import sys -sys.modules.setdefault('numpy', sys.modules['numpypy']) +#import sys +#sys.modules.setdefault('numpy', sys.modules['numpypy']) + + diff --git a/lib_pypy/numpypy/core/fromnumeric.py b/lib_pypy/numpypy/core/fromnumeric.py --- a/lib_pypy/numpypy/core/fromnumeric.py +++ b/lib_pypy/numpypy/core/fromnumeric.py @@ -1133,7 +1133,13 @@ (array([1, 1, 1, 2, 2, 2]), array([0, 1, 2, 0, 1, 2])) """ - raise NotImplementedError('Waiting on interp level method') + try: + nonzero = a.nonzero + except AttributeError: + res = _wrapit(a, 'nonzero') + else: + res = nonzero() + return res def shape(a): diff --git a/pypy/doc/faq.rst b/pypy/doc/faq.rst --- a/pypy/doc/faq.rst +++ b/pypy/doc/faq.rst @@ -356,7 +356,7 @@ attempt to point newcomers at existing alternatives, which are more mainstream and where they will get help from many people.* - *If anybody seriously wants to promote RPython anyway, he is welcome + *If anybody seriously wants to promote RPython anyway, they are welcome to: we won't actively resist such a plan. There are a lot of things that could be done to make RPython a better Java-ish language for example, starting with supporting non-GIL-based multithreading, but we @@ -396,8 +396,8 @@ patch the generated machine code. So the position of the core PyPy developers is that if anyone wants to -make an N+1'th attempt with LLVM, he is welcome, and he will receive a -bit of help on the IRC channel, but he is left with the burden of proof +make an N+1'th attempt with LLVM, they are welcome, and will be happy to +provide help in the IRC channel, but they are left with the burden of proof that it works. ---------------------- diff --git a/pypy/doc/how-to-release.rst b/pypy/doc/how-to-release.rst --- a/pypy/doc/how-to-release.rst +++ b/pypy/doc/how-to-release.rst @@ -25,6 +25,7 @@ necessary; also update the version number in pypy/doc/conf.py, and in pypy/doc/index.rst * update pypy/doc/contributor.rst (and possibly LICENSE) + pypy/doc/tool/makecontributor.py generates the list of contributors * rename pypy/doc/whatsnew_head.rst to whatsnew_VERSION.rst and create a fresh whatsnew_head.rst after the release * update README diff --git a/pypy/doc/whatsnew-head.rst b/pypy/doc/whatsnew-head.rst --- a/pypy/doc/whatsnew-head.rst +++ b/pypy/doc/whatsnew-head.rst @@ -52,6 +52,10 @@ .. branch: ndarray-subtype Allow subclassing ndarray, i.e. matrix +.. branch: pypy-pyarray +Implement much of numpy's c api in cpyext, allows (slow) access to ndarray +from c + .. branch: kill-ootype .. branch: fast-slowpath @@ -82,7 +86,7 @@ .. branch: rewritten-loop-logging .. branch: no-release-gil .. branch: safe-win-mmap -.. branch: boolean-index-cleanup +.. branch: boolean-indexing-cleanup .. branch: nobold-backtrace Work on improving UnionError messages and stack trace displays. @@ -97,3 +101,5 @@ Use subclasses of SpaceOperation instead of SpaceOperator objects. Random cleanups in flowspace. +.. branch: file-support-in-rpython +make open() and friends rpython diff --git a/pypy/module/_pypyjson/test/test__pypyjson.py b/pypy/module/_pypyjson/test/test__pypyjson.py --- a/pypy/module/_pypyjson/test/test__pypyjson.py +++ b/pypy/module/_pypyjson/test/test__pypyjson.py @@ -1,5 +1,5 @@ # -*- encoding: utf-8 -*- -import py +import py, sys from pypy.module._pypyjson.interp_decoder import JSONDecoder def test_skip_whitespace(): @@ -16,6 +16,9 @@ class AppTest(object): spaceconfig = {"objspace.usemodules._pypyjson": True} + def setup_class(cls): + cls.w_run_on_16bit = cls.space.wrap(sys.maxunicode == 65535) + def test_raise_on_bytes(self): import _pypyjson raises(TypeError, _pypyjson.loads, b"42") @@ -177,11 +180,11 @@ raises(ValueError, "_pypyjson.loads('[1: 2]')") raises(ValueError, "_pypyjson.loads('[1, 2')") raises(ValueError, """_pypyjson.loads('["extra comma",]')""") - + def test_unicode_surrogate_pair(self): + if self.run_on_16bit: + skip("XXX fix me or mark definitely skipped") import _pypyjson expected = 'z\U0001d120x' res = _pypyjson.loads('"z\\ud834\\udd20x"') assert res == expected - - 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 @@ -606,7 +606,7 @@ proto = libssl_SSL_CIPHER_get_version(current) if proto: - w_proto = space.wrap(rffi.charp2str(name)) + w_proto = space.wrap(rffi.charp2str(proto)) else: w_proto = space.w_None @@ -683,15 +683,15 @@ w_serial = space.wrap(rffi.charpsize2str(buf, length)) space.setitem(w_retval, space.wrap("serialNumber"), w_serial) - libssl_BIO_reset(biobuf) - notBefore = libssl_X509_get_notBefore(certificate) - libssl_ASN1_TIME_print(biobuf, notBefore) - with lltype.scoped_alloc(rffi.CCHARP.TO, 100) as buf: - length = libssl_BIO_gets(biobuf, buf, 99) - if length < 0: - raise _ssl_seterror(space, None, length) - w_date = space.wrap(rffi.charpsize2str(buf, length)) - space.setitem(w_retval, space.wrap("notBefore"), w_date) + libssl_BIO_reset(biobuf) + notBefore = libssl_X509_get_notBefore(certificate) + libssl_ASN1_TIME_print(biobuf, notBefore) + with lltype.scoped_alloc(rffi.CCHARP.TO, 100) as buf: + length = libssl_BIO_gets(biobuf, buf, 99) + if length < 0: + raise _ssl_seterror(space, None, length) + w_date = space.wrap(rffi.charpsize2str(buf, length)) + space.setitem(w_retval, space.wrap("notBefore"), w_date) libssl_BIO_reset(biobuf) notAfter = libssl_X509_get_notAfter(certificate) 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 @@ -36,6 +36,7 @@ import pypy.module.cpyext.object import pypy.module.cpyext.bytesobject import pypy.module.cpyext.tupleobject +import pypy.module.cpyext.ndarrayobject import pypy.module.cpyext.setobject import pypy.module.cpyext.dictobject import pypy.module.cpyext.longobject diff --git a/pypy/module/cpyext/api.py b/pypy/module/cpyext/api.py --- a/pypy/module/cpyext/api.py +++ b/pypy/module/cpyext/api.py @@ -130,11 +130,7 @@ udir.join('pypy_macros.h').write("/* Will be filled later */\n") globals().update(rffi_platform.configure(CConfig_constants)) -def copy_header_files(dstdir): - assert dstdir.check(dir=True) - headers = include_dir.listdir('*.h') + include_dir.listdir('*.inl') - for name in ("pypy_decl.h", "pypy_macros.h"): - headers.append(udir.join(name)) +def _copy_header_files(headers, dstdir): for header in headers: target = dstdir.join(header.basename) try: @@ -145,6 +141,25 @@ target.chmod(0444) # make the file read-only, to make sure that nobody # edits it by mistake +def copy_header_files(dstdir): + # XXX: 20 lines of code to recursively copy a directory, really?? + assert dstdir.check(dir=True) + headers = include_dir.listdir('*.h') + include_dir.listdir('*.inl') + for name in ("pypy_decl.h", "pypy_macros.h"): + headers.append(udir.join(name)) + _copy_header_files(headers, dstdir) + + try: + dstdir.mkdir('numpy') + except py.error.EEXIST: + pass + numpy_dstdir = dstdir / 'numpy' + + numpy_include_dir = include_dir / 'numpy' + numpy_headers = numpy_include_dir.listdir('*.h') + numpy_include_dir.listdir('*.inl') + _copy_header_files(numpy_headers, numpy_dstdir) + + class NotSpecified(object): pass _NOT_SPECIFIED = NotSpecified() @@ -291,9 +306,23 @@ elif isinstance(input_arg, W_Root): arg = input_arg else: - arg = from_ref(space, + try: + arg = from_ref(space, rffi.cast(PyObject, input_arg)) + except TypeError, e: + err = OperationError(space.w_TypeError, + space.wrap( + "could not cast arg to PyObject")) + if not catch_exception: + raise err + state = space.fromcache(State) + state.set_exception(err) + if is_PyObject(restype): + return None + else: + return api_function.error_value else: + # convert to a wrapped object arg = input_arg newargs += (arg, ) try: @@ -312,7 +341,7 @@ return api_function.error_value if not we_are_translated(): got_integer = isinstance(res, (int, long, float)) - assert got_integer == expect_integer + assert got_integer == expect_integer,'got %r not integer' % res if res is None: return None elif isinstance(res, Reference): @@ -388,6 +417,16 @@ 'PyThread_ReInitTLS', 'PyStructSequence_InitType', 'PyStructSequence_New', + + 'PyFunction_Type', 'PyMethod_Type', 'PyRange_Type', 'PyTraceBack_Type', + + 'PyArray_Type', '_PyArray_FILLWBYTE', '_PyArray_ZEROS', '_PyArray_CopyInto', + + 'Py_DebugFlag', 'Py_VerboseFlag', 'Py_InteractiveFlag', 'Py_InspectFlag', + 'Py_OptimizeFlag', 'Py_NoSiteFlag', 'Py_BytesWarningFlag', 'Py_UseClassExceptionsFlag', + 'Py_FrozenFlag', 'Py_TabcheckFlag', 'Py_UnicodeFlag', 'Py_IgnoreEnvironmentFlag', + 'Py_DivisionWarningFlag', 'Py_DontWriteBytecodeFlag', 'Py_NoUserSiteDirectory', + '_Py_QnewFlag', 'Py_Py3kWarningFlag', 'Py_HashRandomizationFlag', '_Py_PackageContext', ] TYPES = {} GLOBALS = { # this needs to include all prebuilt pto, otherwise segfaults occur @@ -973,6 +1012,8 @@ source_dir / "capsule.c", source_dir / "pysignals.c", source_dir / "pythread.c", + source_dir / "ndarrayobject.c", + source_dir / "missing.c", ], separate_module_sources=separate_module_sources, export_symbols=export_symbols_eci, diff --git a/pypy/module/cpyext/include/Python.h b/pypy/module/cpyext/include/Python.h --- a/pypy/module/cpyext/include/Python.h +++ b/pypy/module/cpyext/include/Python.h @@ -127,6 +127,9 @@ #include "pysignals.h" #include "pythread.h" +/* Missing definitions */ +#include "missing.h" + // XXX This shouldn't be included here #include "structmember.h" diff --git a/pypy/module/cpyext/include/boolobject.h b/pypy/module/cpyext/include/boolobject.h --- a/pypy/module/cpyext/include/boolobject.h +++ b/pypy/module/cpyext/include/boolobject.h @@ -7,6 +7,8 @@ extern "C" { #endif +#define PyBoolObject PyIntObject + #define Py_False ((PyObject *) &_Py_ZeroStruct) #define Py_True ((PyObject *) &_Py_TrueStruct) diff --git a/pypy/module/cpyext/include/complexobject.h b/pypy/module/cpyext/include/complexobject.h --- a/pypy/module/cpyext/include/complexobject.h +++ b/pypy/module/cpyext/include/complexobject.h @@ -6,6 +6,9 @@ extern "C" { #endif +/* fake PyComplexObject so that code that doesn't do direct field access works */ +#define PyComplexObject PyObject + typedef struct Py_complex_t { double real; double imag; @@ -13,6 +16,7 @@ /* generated function */ PyAPI_FUNC(void) _PyComplex_AsCComplex(PyObject *, Py_complex *); +PyAPI_FUNC(PyObject *) _PyComplex_FromCComplex(Py_complex *); Py_LOCAL_INLINE(Py_complex) PyComplex_AsCComplex(PyObject *obj) { @@ -21,7 +25,12 @@ return result; } -#define PyComplex_FromCComplex(c) _PyComplex_FromCComplex(&c) +// shmuller 2013/07/30: Make a function, since macro will fail in C++ due to +// const correctness if called with "const Py_complex" +//#define PyComplex_FromCComplex(c) _PyComplex_FromCComplex(&c) +Py_LOCAL_INLINE(PyObject *) PyComplex_FromCComplex(Py_complex c) { + return _PyComplex_FromCComplex(&c); +} #ifdef __cplusplus } diff --git a/pypy/module/cpyext/include/funcobject.h b/pypy/module/cpyext/include/funcobject.h --- a/pypy/module/cpyext/include/funcobject.h +++ b/pypy/module/cpyext/include/funcobject.h @@ -12,6 +12,8 @@ PyObject *func_name; /* The __name__ attribute, a string object */ } PyFunctionObject; +PyAPI_DATA(PyTypeObject) PyFunction_Type; + #define PyFunction_GET_CODE(obj) PyFunction_GetCode((PyObject*)(obj)) #define PyMethod_GET_FUNCTION(obj) PyMethod_Function((PyObject*)(obj)) diff --git a/pypy/module/cpyext/include/missing.h b/pypy/module/cpyext/include/missing.h new file mode 100644 --- /dev/null +++ b/pypy/module/cpyext/include/missing.h @@ -0,0 +1,17 @@ + +/* Definitions from missing header files */ + +#ifndef Py_MISSING_H +#define Py_MISSING_H +#ifdef __cplusplus +extern "C" { +#endif + +PyAPI_DATA(PyTypeObject) PyMethod_Type; +PyAPI_DATA(PyTypeObject) PyRange_Type; +PyAPI_DATA(PyTypeObject) PyTraceBack_Type; + +#ifdef __cplusplus +} +#endif +#endif /* !Py_MISSING_H */ diff --git a/pypy/module/cpyext/include/modsupport.h b/pypy/module/cpyext/include/modsupport.h --- a/pypy/module/cpyext/include/modsupport.h +++ b/pypy/module/cpyext/include/modsupport.h @@ -60,6 +60,7 @@ #define PyMODINIT_FUNC PyObject* #endif +PyAPI_DATA(char *) _Py_PackageContext; #ifdef __cplusplus } diff --git a/pypy/module/cpyext/include/numpy/arrayobject.h b/pypy/module/cpyext/include/numpy/arrayobject.h new file mode 100644 --- /dev/null +++ b/pypy/module/cpyext/include/numpy/arrayobject.h @@ -0,0 +1,239 @@ + +/* NDArray object interface - S. H. Muller, 2013/07/26 */ + +#ifndef Py_NDARRAYOBJECT_H +#define Py_NDARRAYOBJECT_H +#ifdef __cplusplus +extern "C" { +#endif + +#include "old_defines.h" + +#define NPY_INLINE +#define NPY_UNUSED(x) x +#define PyArray_MAX(a,b) (((a)>(b))?(a):(b)) +#define PyArray_MIN(a,b) (((a)<(b))?(a):(b)) + +/* fake PyArrayObject so that code that doesn't do direct field access works */ +#define PyArrayObject PyObject +#define PyArray_Descr PyObject + +extern PyTypeObject PyArray_Type; + +typedef unsigned char npy_bool; +typedef unsigned char npy_uint8; +typedef int npy_int; + +#ifndef npy_intp +#define npy_intp long +#endif +#ifndef NPY_INTP_FMT +#define NPY_INTP_FMT "ld" +#endif +#ifndef import_array +#define import_array() +#endif + +#define NPY_MAXDIMS 32 + +typedef struct { + npy_intp *ptr; + int len; +} PyArray_Dims; + +/* data types copied from numpy/ndarraytypes.h + * keep numbers in sync with micronumpy.interp_dtype.DTypeCache + */ +enum NPY_TYPES { NPY_BOOL=0, + NPY_BYTE, NPY_UBYTE, + NPY_SHORT, NPY_USHORT, + NPY_INT, NPY_UINT, + NPY_LONG, NPY_ULONG, + NPY_LONGLONG, NPY_ULONGLONG, + NPY_FLOAT, NPY_DOUBLE, NPY_LONGDOUBLE, + NPY_CFLOAT, NPY_CDOUBLE, NPY_CLONGDOUBLE, + NPY_OBJECT=17, + NPY_STRING, NPY_UNICODE, + NPY_VOID, + /* + * New 1.6 types appended, may be integrated + * into the above in 2.0. + */ + NPY_DATETIME, NPY_TIMEDELTA, NPY_HALF, + + NPY_NTYPES, + NPY_NOTYPE, + NPY_CHAR, /* special flag */ + NPY_USERDEF=256, /* leave room for characters */ + + /* The number of types not including the new 1.6 types */ + NPY_NTYPES_ABI_COMPATIBLE=21 +}; + +#define NPY_INT8 NPY_BYTE +#define NPY_UINT8 NPY_UBYTE +#define NPY_INT16 NPY_SHORT +#define NPY_UINT16 NPY_USHORT +#define NPY_INT32 NPY_INT +#define NPY_UINT32 NPY_UINT +#define NPY_INT64 NPY_LONG +#define NPY_UINT64 NPY_ULONG +#define NPY_FLOAT32 NPY_FLOAT +#define NPY_FLOAT64 NPY_DOUBLE +#define NPY_COMPLEX32 NPY_CFLOAT +#define NPY_COMPLEX64 NPY_CDOUBLE + +#define PyTypeNum_ISBOOL(type) ((type) == NPY_BOOL) +#define PyTypeNum_ISINTEGER(type) (((type) >= NPY_BYTE) && \ + ((type) <= NPY_ULONGLONG)) +#define PyTypeNum_ISFLOAT(type) ((((type) >= NPY_FLOAT) && \ + ((type) <= NPY_LONGDOUBLE)) || \ + ((type) == NPY_HALF)) +#define PyTypeNum_ISCOMPLEX(type) (((type) >= NPY_CFLOAT) && \ + ((type) <= NPY_CLONGDOUBLE)) + +#define PyArray_ISBOOL(arr) (PyTypeNum_ISBOOL(PyArray_TYPE(arr))) +#define PyArray_ISINTEGER(arr) (PyTypeNum_ISINTEGER(PyArray_TYPE(arr))) +#define PyArray_ISFLOAT(arr) (PyTypeNum_ISFLOAT(PyArray_TYPE(arr))) +#define PyArray_ISCOMPLEX(arr) (PyTypeNum_ISCOMPLEX(PyArray_TYPE(arr))) + + +/* flags */ +#define NPY_ARRAY_C_CONTIGUOUS 0x0001 +#define NPY_ARRAY_F_CONTIGUOUS 0x0002 +#define NPY_ARRAY_OWNDATA 0x0004 +#define NPY_ARRAY_FORCECAST 0x0010 +#define NPY_ARRAY_ENSURECOPY 0x0020 +#define NPY_ARRAY_ENSUREARRAY 0x0040 +#define NPY_ARRAY_ELEMENTSTRIDES 0x0080 +#define NPY_ARRAY_ALIGNED 0x0100 +#define NPY_ARRAY_NOTSWAPPED 0x0200 +#define NPY_ARRAY_WRITEABLE 0x0400 +#define NPY_ARRAY_UPDATEIFCOPY 0x1000 + +#define NPY_ARRAY_BEHAVED (NPY_ARRAY_ALIGNED | \ + NPY_ARRAY_WRITEABLE) +#define NPY_ARRAY_BEHAVED_NS (NPY_ARRAY_ALIGNED | \ + NPY_ARRAY_WRITEABLE | \ + NPY_ARRAY_NOTSWAPPED) +#define NPY_ARRAY_CARRAY (NPY_ARRAY_C_CONTIGUOUS | \ + NPY_ARRAY_BEHAVED) +#define NPY_ARRAY_CARRAY_RO (NPY_ARRAY_C_CONTIGUOUS | \ + NPY_ARRAY_ALIGNED) +#define NPY_ARRAY_FARRAY (NPY_ARRAY_F_CONTIGUOUS | \ + NPY_ARRAY_BEHAVED) +#define NPY_ARRAY_FARRAY_RO (NPY_ARRAY_F_CONTIGUOUS | \ + NPY_ARRAY_ALIGNED) +#define NPY_ARRAY_DEFAULT (NPY_ARRAY_CARRAY) +#define NPY_ARRAY_IN_ARRAY (NPY_ARRAY_CARRAY_RO) +#define NPY_ARRAY_OUT_ARRAY (NPY_ARRAY_CARRAY) +#define NPY_ARRAY_INOUT_ARRAY (NPY_ARRAY_CARRAY | \ + NPY_ARRAY_UPDATEIFCOPY) +#define NPY_ARRAY_IN_FARRAY (NPY_ARRAY_FARRAY_RO) +#define NPY_ARRAY_OUT_FARRAY (NPY_ARRAY_FARRAY) +#define NPY_ARRAY_INOUT_FARRAY (NPY_ARRAY_FARRAY | \ + NPY_ARRAY_UPDATEIFCOPY) + +#define NPY_ARRAY_UPDATE_ALL (NPY_ARRAY_C_CONTIGUOUS | \ + NPY_ARRAY_F_CONTIGUOUS | \ + NPY_ARRAY_ALIGNED) + +#define NPY_FARRAY NPY_ARRAY_FARRAY +#define NPY_CARRAY NPY_ARRAY_CARRAY + +#define PyArray_CHKFLAGS(m, flags) (PyArray_FLAGS(m) & (flags)) + +#define PyArray_ISCONTIGUOUS(m) PyArray_CHKFLAGS(m, NPY_ARRAY_C_CONTIGUOUS) +#define PyArray_ISWRITEABLE(m) PyArray_CHKFLAGS(m, NPY_ARRAY_WRITEABLE) +#define PyArray_ISALIGNED(m) PyArray_CHKFLAGS(m, NPY_ARRAY_ALIGNED) + +#define PyArray_IS_C_CONTIGUOUS(m) PyArray_CHKFLAGS(m, NPY_ARRAY_C_CONTIGUOUS) +#define PyArray_IS_F_CONTIGUOUS(m) PyArray_CHKFLAGS(m, NPY_ARRAY_F_CONTIGUOUS) + +#define PyArray_FLAGSWAP(m, flags) (PyArray_CHKFLAGS(m, flags) && \ + PyArray_ISNOTSWAPPED(m)) + +#define PyArray_ISCARRAY(m) PyArray_FLAGSWAP(m, NPY_ARRAY_CARRAY) +#define PyArray_ISCARRAY_RO(m) PyArray_FLAGSWAP(m, NPY_ARRAY_CARRAY_RO) +#define PyArray_ISFARRAY(m) PyArray_FLAGSWAP(m, NPY_ARRAY_FARRAY) +#define PyArray_ISFARRAY_RO(m) PyArray_FLAGSWAP(m, NPY_ARRAY_FARRAY_RO) +#define PyArray_ISBEHAVED(m) PyArray_FLAGSWAP(m, NPY_ARRAY_BEHAVED) +#define PyArray_ISBEHAVED_RO(m) PyArray_FLAGSWAP(m, NPY_ARRAY_ALIGNED) + +#define PyArray_ISONESEGMENT(arr) (1) +#define PyArray_ISNOTSWAPPED(arr) (1) +#define PyArray_ISBYTESWAPPED(arr) (0) + + +/* functions */ +#ifndef PyArray_NDIM + +#define PyArray_Check _PyArray_Check +#define PyArray_CheckExact _PyArray_CheckExact +#define PyArray_FLAGS _PyArray_FLAGS + +#define PyArray_NDIM _PyArray_NDIM +#define PyArray_DIM _PyArray_DIM +#define PyArray_STRIDE _PyArray_STRIDE +#define PyArray_SIZE _PyArray_SIZE +#define PyArray_ITEMSIZE _PyArray_ITEMSIZE +#define PyArray_NBYTES _PyArray_NBYTES +#define PyArray_TYPE _PyArray_TYPE +#define PyArray_DATA _PyArray_DATA + +#define PyArray_Size PyArray_SIZE +#define PyArray_BYTES(arr) ((char *)PyArray_DATA(arr)) + +#define PyArray_FromAny _PyArray_FromAny +#define PyArray_FromObject _PyArray_FromObject +#define PyArray_ContiguousFromObject PyArray_FromObject +#define PyArray_ContiguousFromAny PyArray_FromObject + +#define PyArray_FROMANY(obj, typenum, min, max, requirements) (obj) +#define PyArray_FROM_OTF(obj, typenum, requirements) \ + PyArray_FromObject(obj, typenum, 0, 0) + +#define PyArray_New _PyArray_New +#define PyArray_SimpleNew _PyArray_SimpleNew +#define PyArray_SimpleNewFromData _PyArray_SimpleNewFromData +#define PyArray_SimpleNewFromDataOwning _PyArray_SimpleNewFromDataOwning + +#define PyArray_EMPTY(nd, dims, type_num, fortran) \ + PyArray_SimpleNew(nd, dims, type_num) + +void _PyArray_FILLWBYTE(PyObject* obj, int val); +PyObject* _PyArray_ZEROS(int nd, npy_intp* dims, int type_num, int fortran); +int _PyArray_CopyInto(PyArrayObject* dest, PyArrayObject* src); + +#define PyArray_FILLWBYTE _PyArray_FILLWBYTE +#define PyArray_ZEROS _PyArray_ZEROS +#define PyArray_CopyInto _PyArray_CopyInto + +#define PyArray_Resize(self, newshape, refcheck, fortran) (NULL) + +/* Don't use these in loops! */ + +#define PyArray_GETPTR1(obj, i) ((void *)(PyArray_BYTES(obj) + \ + (i)*PyArray_STRIDE(obj,0))) + +#define PyArray_GETPTR2(obj, i, j) ((void *)(PyArray_BYTES(obj) + \ + (i)*PyArray_STRIDE(obj,0) + \ + (j)*PyArray_STRIDE(obj,1))) + +#define PyArray_GETPTR3(obj, i, j, k) ((void *)(PyArray_BYTES(obj) + \ + (i)*PyArray_STRIDE(obj,0) + \ + (j)*PyArray_STRIDE(obj,1) + \ + (k)*PyArray_STRIDE(obj,2))) + +#define PyArray_GETPTR4(obj, i, j, k, l) ((void *)(PyArray_BYTES(obj) + \ + (i)*PyArray_STRIDE(obj,0) + \ + (j)*PyArray_STRIDE(obj,1) + \ + (k)*PyArray_STRIDE(obj,2) + \ + (l)*PyArray_STRIDE(obj,3))) + +#endif + +#ifdef __cplusplus +} +#endif +#endif /* !Py_NDARRAYOBJECT_H */ diff --git a/pypy/module/cpyext/include/numpy/npy_3kcompat.h b/pypy/module/cpyext/include/numpy/npy_3kcompat.h new file mode 100644 diff --git a/pypy/module/cpyext/include/numpy/old_defines.h b/pypy/module/cpyext/include/numpy/old_defines.h new file mode 100644 --- /dev/null +++ b/pypy/module/cpyext/include/numpy/old_defines.h @@ -0,0 +1,189 @@ +/* This header is deprecated as of NumPy 1.7 */ +#ifndef OLD_DEFINES_H +#define OLD_DEFINES_H + +/* +#if defined(NPY_NO_DEPRECATED_API) && NPY_NO_DEPRECATED_API >= NPY_1_7_API_VERSION +#error The header "old_defines.h" is deprecated as of NumPy 1.7. +#endif +*/ + +#define NDARRAY_VERSION NPY_VERSION + +#define PyArray_MIN_BUFSIZE NPY_MIN_BUFSIZE +#define PyArray_MAX_BUFSIZE NPY_MAX_BUFSIZE +#define PyArray_BUFSIZE NPY_BUFSIZE + +#define PyArray_PRIORITY NPY_PRIORITY +#define PyArray_SUBTYPE_PRIORITY NPY_PRIORITY +#define PyArray_NUM_FLOATTYPE NPY_NUM_FLOATTYPE + +#define NPY_MAX PyArray_MAX +#define NPY_MIN PyArray_MIN + +#define PyArray_TYPES NPY_TYPES +#define PyArray_BOOL NPY_BOOL +#define PyArray_BYTE NPY_BYTE +#define PyArray_UBYTE NPY_UBYTE +#define PyArray_SHORT NPY_SHORT +#define PyArray_USHORT NPY_USHORT +#define PyArray_INT NPY_INT +#define PyArray_UINT NPY_UINT +#define PyArray_LONG NPY_LONG +#define PyArray_ULONG NPY_ULONG +#define PyArray_LONGLONG NPY_LONGLONG +#define PyArray_ULONGLONG NPY_ULONGLONG +#define PyArray_HALF NPY_HALF +#define PyArray_FLOAT NPY_FLOAT +#define PyArray_DOUBLE NPY_DOUBLE +#define PyArray_LONGDOUBLE NPY_LONGDOUBLE +#define PyArray_CFLOAT NPY_CFLOAT +#define PyArray_CDOUBLE NPY_CDOUBLE +#define PyArray_CLONGDOUBLE NPY_CLONGDOUBLE +#define PyArray_OBJECT NPY_OBJECT +#define PyArray_STRING NPY_STRING +#define PyArray_UNICODE NPY_UNICODE +#define PyArray_VOID NPY_VOID +#define PyArray_DATETIME NPY_DATETIME +#define PyArray_TIMEDELTA NPY_TIMEDELTA +#define PyArray_NTYPES NPY_NTYPES +#define PyArray_NOTYPE NPY_NOTYPE +#define PyArray_CHAR NPY_CHAR +#define PyArray_USERDEF NPY_USERDEF +#define PyArray_NUMUSERTYPES NPY_NUMUSERTYPES + +#define PyArray_INTP NPY_INTP +#define PyArray_UINTP NPY_UINTP + +#define PyArray_INT8 NPY_INT8 +#define PyArray_UINT8 NPY_UINT8 +#define PyArray_INT16 NPY_INT16 +#define PyArray_UINT16 NPY_UINT16 +#define PyArray_INT32 NPY_INT32 +#define PyArray_UINT32 NPY_UINT32 + +#ifdef NPY_INT64 +#define PyArray_INT64 NPY_INT64 +#define PyArray_UINT64 NPY_UINT64 +#endif + +#ifdef NPY_INT128 +#define PyArray_INT128 NPY_INT128 +#define PyArray_UINT128 NPY_UINT128 +#endif + +#ifdef NPY_FLOAT16 +#define PyArray_FLOAT16 NPY_FLOAT16 +#define PyArray_COMPLEX32 NPY_COMPLEX32 +#endif + +#ifdef NPY_FLOAT80 +#define PyArray_FLOAT80 NPY_FLOAT80 +#define PyArray_COMPLEX160 NPY_COMPLEX160 +#endif + +#ifdef NPY_FLOAT96 +#define PyArray_FLOAT96 NPY_FLOAT96 +#define PyArray_COMPLEX192 NPY_COMPLEX192 +#endif + +#ifdef NPY_FLOAT128 +#define PyArray_FLOAT128 NPY_FLOAT128 +#define PyArray_COMPLEX256 NPY_COMPLEX256 +#endif + +#define PyArray_FLOAT32 NPY_FLOAT32 +#define PyArray_COMPLEX64 NPY_COMPLEX64 +#define PyArray_FLOAT64 NPY_FLOAT64 +#define PyArray_COMPLEX128 NPY_COMPLEX128 + + +#define PyArray_TYPECHAR NPY_TYPECHAR +#define PyArray_BOOLLTR NPY_BOOLLTR +#define PyArray_BYTELTR NPY_BYTELTR +#define PyArray_UBYTELTR NPY_UBYTELTR +#define PyArray_SHORTLTR NPY_SHORTLTR +#define PyArray_USHORTLTR NPY_USHORTLTR +#define PyArray_INTLTR NPY_INTLTR +#define PyArray_UINTLTR NPY_UINTLTR +#define PyArray_LONGLTR NPY_LONGLTR +#define PyArray_ULONGLTR NPY_ULONGLTR +#define PyArray_LONGLONGLTR NPY_LONGLONGLTR +#define PyArray_ULONGLONGLTR NPY_ULONGLONGLTR +#define PyArray_HALFLTR NPY_HALFLTR +#define PyArray_FLOATLTR NPY_FLOATLTR +#define PyArray_DOUBLELTR NPY_DOUBLELTR +#define PyArray_LONGDOUBLELTR NPY_LONGDOUBLELTR +#define PyArray_CFLOATLTR NPY_CFLOATLTR +#define PyArray_CDOUBLELTR NPY_CDOUBLELTR +#define PyArray_CLONGDOUBLELTR NPY_CLONGDOUBLELTR +#define PyArray_OBJECTLTR NPY_OBJECTLTR +#define PyArray_STRINGLTR NPY_STRINGLTR +#define PyArray_STRINGLTR2 NPY_STRINGLTR2 +#define PyArray_UNICODELTR NPY_UNICODELTR +#define PyArray_VOIDLTR NPY_VOIDLTR +#define PyArray_DATETIMELTR NPY_DATETIMELTR +#define PyArray_TIMEDELTALTR NPY_TIMEDELTALTR +#define PyArray_CHARLTR NPY_CHARLTR +#define PyArray_INTPLTR NPY_INTPLTR +#define PyArray_UINTPLTR NPY_UINTPLTR +#define PyArray_GENBOOLLTR NPY_GENBOOLLTR +#define PyArray_SIGNEDLTR NPY_SIGNEDLTR +#define PyArray_UNSIGNEDLTR NPY_UNSIGNEDLTR +#define PyArray_FLOATINGLTR NPY_FLOATINGLTR +#define PyArray_COMPLEXLTR NPY_COMPLEXLTR + +#define PyArray_QUICKSORT NPY_QUICKSORT +#define PyArray_HEAPSORT NPY_HEAPSORT +#define PyArray_MERGESORT NPY_MERGESORT +#define PyArray_SORTKIND NPY_SORTKIND +#define PyArray_NSORTS NPY_NSORTS + +#define PyArray_NOSCALAR NPY_NOSCALAR +#define PyArray_BOOL_SCALAR NPY_BOOL_SCALAR +#define PyArray_INTPOS_SCALAR NPY_INTPOS_SCALAR +#define PyArray_INTNEG_SCALAR NPY_INTNEG_SCALAR +#define PyArray_FLOAT_SCALAR NPY_FLOAT_SCALAR +#define PyArray_COMPLEX_SCALAR NPY_COMPLEX_SCALAR +#define PyArray_OBJECT_SCALAR NPY_OBJECT_SCALAR +#define PyArray_SCALARKIND NPY_SCALARKIND +#define PyArray_NSCALARKINDS NPY_NSCALARKINDS + +#define PyArray_ANYORDER NPY_ANYORDER +#define PyArray_CORDER NPY_CORDER +#define PyArray_FORTRANORDER NPY_FORTRANORDER +#define PyArray_ORDER NPY_ORDER + +#define PyDescr_ISBOOL PyDataType_ISBOOL +#define PyDescr_ISUNSIGNED PyDataType_ISUNSIGNED +#define PyDescr_ISSIGNED PyDataType_ISSIGNED +#define PyDescr_ISINTEGER PyDataType_ISINTEGER +#define PyDescr_ISFLOAT PyDataType_ISFLOAT +#define PyDescr_ISNUMBER PyDataType_ISNUMBER +#define PyDescr_ISSTRING PyDataType_ISSTRING +#define PyDescr_ISCOMPLEX PyDataType_ISCOMPLEX +#define PyDescr_ISPYTHON PyDataType_ISPYTHON +#define PyDescr_ISFLEXIBLE PyDataType_ISFLEXIBLE +#define PyDescr_ISUSERDEF PyDataType_ISUSERDEF +#define PyDescr_ISEXTENDED PyDataType_ISEXTENDED +#define PyDescr_ISOBJECT PyDataType_ISOBJECT +#define PyDescr_HASFIELDS PyDataType_HASFIELDS + +#define PyArray_LITTLE NPY_LITTLE +#define PyArray_BIG NPY_BIG +#define PyArray_NATIVE NPY_NATIVE +#define PyArray_SWAP NPY_SWAP +#define PyArray_IGNORE NPY_IGNORE + +#define PyArray_NATBYTE NPY_NATBYTE +#define PyArray_OPPBYTE NPY_OPPBYTE + +#define PyArray_MAX_ELSIZE NPY_MAX_ELSIZE + +#define PyArray_USE_PYMEM NPY_USE_PYMEM + +#define PyArray_RemoveLargest PyArray_RemoveSmallest + +#define PyArray_UCS4 npy_ucs4 + +#endif diff --git a/pypy/module/cpyext/include/pythonrun.h b/pypy/module/cpyext/include/pythonrun.h --- a/pypy/module/cpyext/include/pythonrun.h +++ b/pypy/module/cpyext/include/pythonrun.h @@ -8,12 +8,30 @@ PyAPI_FUNC(void) Py_FatalError(const char *message); -/* the -3 option will probably not be implemented */ -#define Py_Py3kWarningFlag 0 +/* taken from Python-2.7.3/Include/pydebug.h */ +PyAPI_DATA(int) Py_DebugFlag; +PyAPI_DATA(int) Py_VerboseFlag; +PyAPI_DATA(int) Py_InteractiveFlag; +PyAPI_DATA(int) Py_InspectFlag; +PyAPI_DATA(int) Py_OptimizeFlag; +PyAPI_DATA(int) Py_NoSiteFlag; +PyAPI_DATA(int) Py_BytesWarningFlag; +PyAPI_DATA(int) Py_UseClassExceptionsFlag; +PyAPI_DATA(int) Py_FrozenFlag; +PyAPI_DATA(int) Py_TabcheckFlag; +PyAPI_DATA(int) Py_UnicodeFlag; +PyAPI_DATA(int) Py_IgnoreEnvironmentFlag; +PyAPI_DATA(int) Py_DivisionWarningFlag; +PyAPI_DATA(int) Py_DontWriteBytecodeFlag; +PyAPI_DATA(int) Py_NoUserSiteDirectory; +/* _XXX Py_QnewFlag should go away in 3.0. It's true iff -Qnew is passed, + * on the command line, and is used in 2.2 by ceval.c to make all "/" divisions + * true divisions (which they will be in 3.0). */ +PyAPI_DATA(int) _Py_QnewFlag; +/* Warn about 3.x issues */ +PyAPI_DATA(int) Py_Py3kWarningFlag; +PyAPI_DATA(int) Py_HashRandomizationFlag; -#define Py_FrozenFlag 0 -#define Py_VerboseFlag 0 -#define Py_DebugFlag 1 typedef struct { int cf_flags; /* bitmask of CO_xxx flags relevant to future */ diff --git a/pypy/module/cpyext/ndarrayobject.py b/pypy/module/cpyext/ndarrayobject.py new file mode 100644 --- /dev/null +++ b/pypy/module/cpyext/ndarrayobject.py @@ -0,0 +1,246 @@ +""" + +Numpy C-API for PyPy - S. H. Muller, 2013/07/26 +""" + +from pypy.interpreter.error import OperationError +from rpython.rtyper.lltypesystem import rffi, lltype +from pypy.module.cpyext.api import cpython_api, Py_ssize_t, CANNOT_FAIL +from pypy.module.cpyext.api import PyObject +from pypy.module.micronumpy.interp_numarray import W_NDimArray, array +from pypy.module.micronumpy.interp_dtype import get_dtype_cache, W_Dtype +from pypy.module.micronumpy.arrayimpl.concrete import ConcreteArray +from pypy.module.micronumpy.arrayimpl.scalar import Scalar +from rpython.rlib.rawstorage import RAW_STORAGE_PTR + +NPY_C_CONTIGUOUS = 0x0001 +NPY_F_CONTIGUOUS = 0x0002 +NPY_OWNDATA = 0x0004 +NPY_FORCECAST = 0x0010 +NPY_ENSURECOPY = 0x0020 +NPY_ENSUREARRAY = 0x0040 +NPY_ELEMENTSTRIDES = 0x0080 +NPY_ALIGNED = 0x0100 +NPY_NOTSWAPPED = 0x0200 +NPY_WRITEABLE = 0x0400 +NPY_UPDATEIFCOPY = 0x1000 + +NPY_BEHAVED = NPY_ALIGNED | NPY_WRITEABLE +NPY_BEHAVED_NS = NPY_ALIGNED | NPY_WRITEABLE | NPY_NOTSWAPPED +NPY_CARRAY = NPY_C_CONTIGUOUS | NPY_BEHAVED +NPY_CARRAY_RO = NPY_C_CONTIGUOUS | NPY_ALIGNED +NPY_FARRAY = NPY_F_CONTIGUOUS | NPY_BEHAVED +NPY_FARRAY_RO = NPY_F_CONTIGUOUS | NPY_ALIGNED +NPY_DEFAULT = NPY_CARRAY +NPY_IN = NPY_CARRAY_RO +NPY_OUT = NPY_CARRAY +NPY_INOUT = NPY_CARRAY | NPY_UPDATEIFCOPY +NPY_IN_FARRAY = NPY_FARRAY_RO +NPY_OUT_FARRAY = NPY_FARRAY +NPY_INOUT_FARRAY = NPY_FARRAY | NPY_UPDATEIFCOPY +NPY_CONTIGUOUS = NPY_C_CONTIGUOUS | NPY_F_CONTIGUOUS +NPY_UPDATE_ALL = NPY_CONTIGUOUS | NPY_ALIGNED + + +# the asserts are needed, otherwise the translation fails + + at cpython_api([PyObject], rffi.INT_real, error=CANNOT_FAIL) +def _PyArray_Check(space, w_obj): + w_obj_type = space.type(w_obj) + w_type = space.gettypeobject(W_NDimArray.typedef) + return (space.is_w(w_obj_type, w_type) or + space.is_true(space.issubtype(w_obj_type, w_type))) + + at cpython_api([PyObject], rffi.INT_real, error=CANNOT_FAIL) +def _PyArray_CheckExact(space, w_obj): + w_obj_type = space.type(w_obj) + w_type = space.gettypeobject(W_NDimArray.typedef) + return space.is_w(w_obj_type, w_type) + + at cpython_api([PyObject], rffi.INT_real, error=CANNOT_FAIL) +def _PyArray_FLAGS(space, w_array): + assert isinstance(w_array, W_NDimArray) + flags = NPY_BEHAVED_NS + if isinstance(w_array.implementation, ConcreteArray): + flags |= NPY_OWNDATA + if len(w_array.get_shape()) < 2: + flags |= NPY_CONTIGUOUS + elif w_array.implementation.order == 'C': + flags |= NPY_C_CONTIGUOUS + else: + flags |= NPY_F_CONTIGUOUS + return flags + + at cpython_api([PyObject], rffi.INT_real, error=CANNOT_FAIL) +def _PyArray_NDIM(space, w_array): + assert isinstance(w_array, W_NDimArray) + return len(w_array.get_shape()) + + at cpython_api([PyObject, Py_ssize_t], Py_ssize_t, error=CANNOT_FAIL) +def _PyArray_DIM(space, w_array, n): + assert isinstance(w_array, W_NDimArray) + return w_array.get_shape()[n] + + at cpython_api([PyObject, Py_ssize_t], Py_ssize_t, error=CANNOT_FAIL) +def _PyArray_STRIDE(space, w_array, n): + assert isinstance(w_array, W_NDimArray) + return w_array.implementation.get_strides()[n] + + at cpython_api([PyObject], Py_ssize_t, error=CANNOT_FAIL) +def _PyArray_SIZE(space, w_array): + assert isinstance(w_array, W_NDimArray) + return w_array.get_size() + + at cpython_api([PyObject], rffi.INT_real, error=CANNOT_FAIL) +def _PyArray_ITEMSIZE(space, w_array): + assert isinstance(w_array, W_NDimArray) + return w_array.get_dtype().get_size() + + at cpython_api([PyObject], Py_ssize_t, error=CANNOT_FAIL) +def _PyArray_NBYTES(space, w_array): + assert isinstance(w_array, W_NDimArray) + return w_array.get_size() * w_array.get_dtype().get_size() + + at cpython_api([PyObject], rffi.INT_real, error=CANNOT_FAIL) +def _PyArray_TYPE(space, w_array): + assert isinstance(w_array, W_NDimArray) + return w_array.get_dtype().num + + + at cpython_api([PyObject], rffi.VOIDP, error=CANNOT_FAIL) +def _PyArray_DATA(space, w_array): + # fails on scalars - see PyArray_FromAny() + assert isinstance(w_array, W_NDimArray) + return rffi.cast(rffi.VOIDP, w_array.implementation.storage) + +PyArray_Descr = PyObject +NULL = lltype.nullptr(rffi.VOIDP.TO) + + at cpython_api([PyObject, PyArray_Descr, Py_ssize_t, Py_ssize_t, Py_ssize_t, rffi.VOIDP], + PyObject) +def _PyArray_FromAny(space, w_obj, w_dtype, min_depth, max_depth, requirements, context): + """ This is the main function used to obtain an array from any nested + sequence, or object that exposes the array interface, op. The + parameters allow specification of the required dtype, the + minimum (min_depth) and maximum (max_depth) number of dimensions + acceptable, and other requirements for the array. + + The dtype argument needs to be a PyArray_Descr structure indicating + the desired data-type (including required byteorder). The dtype + argument may be NULL, indicating that any data-type (and byteorder) + is acceptable. + Unless FORCECAST is present in flags, this call will generate an error + if the data type cannot be safely obtained from the object. If you + want to use NULL for the dtype and ensure the array is notswapped then + use PyArray_CheckFromAny. + + A value of 0 for either of the depth parameters causes the parameter + to be ignored. + + Any of the following array flags can be added (e.g. using |) to get + the requirements argument. If your code can handle general (e.g. + strided, byte-swapped, or unaligned arrays) then requirements + may be 0. Also, if op is not already an array (or does not expose + the array interface), then a new array will be created (and filled + from op using the sequence protocol). The new array will have + NPY_DEFAULT as its flags member. + + The context argument is passed to the __array__ method of op and is + only used if the array is constructed that way. Almost always this + parameter is NULL. + """ + if min_depth !=0 or max_depth != 0: + raise OperationError(space.w_NotImplementedError, space.wrap( + '_PyArray_FromAny called with not-implemented min_dpeth or max_depth argument')) + if requirements not in (0, NPY_DEFAULT): + raise OperationError(space.w_NotImplementedError, space.wrap( + '_PyArray_FromAny called with not-implemented requirements argument')) + w_array = array(space, w_obj, w_dtype=w_dtype, copy=False) + if w_array.is_scalar(): + # since PyArray_DATA() fails on scalars, create a 1D array and set empty + # shape. So the following combination works for *reading* scalars: + # PyObject *arr = PyArray_FromAny(obj); + # int nd = PyArray_NDIM(arr); + # void *data = PyArray_DATA(arr); + impl = w_array.implementation + w_array = W_NDimArray.from_shape(space, [1], impl.dtype) + w_array.implementation.setitem(0, impl.value) + w_array.implementation.shape = [] + return w_array + + at cpython_api([PyObject, Py_ssize_t, Py_ssize_t, Py_ssize_t], PyObject) +def _PyArray_FromObject(space, w_obj, typenum, min_depth, max_depth): + try: + dtype = get_dtype_cache(space).dtypes_by_num[typenum] + except KeyError: + raise OperationError(space.w_ValueError, space.wrap( + '_PyArray_FromObject called with invalid dtype %d' % typenum)) + try: + return _PyArray_FromAny(space, w_obj, dtype, min_depth, max_depth, + 0, NULL); + except OperationError, e: + if e.match(space, space.w_NotImplementedError): + errstr = space.str_w(e.get_w_value(space)) + errstr = '_PyArray_FromObject' + errstr[16:] + raise OperationError(space.w_NotImplementedError, space.wrap( + errstr)) + raise + +def get_shape_and_dtype(space, nd, dims, typenum): + shape = [] + for i in range(nd): + shape.append(rffi.cast(rffi.LONG, dims[i])) + dtype = get_dtype_cache(space).dtypes_by_num[typenum] + return shape, dtype + +def simple_new(space, nd, dims, typenum, + order='C', owning=False, w_subtype=None): + shape, dtype = get_shape_and_dtype(space, nd, dims, typenum) + return W_NDimArray.from_shape(space, shape, dtype) + +def simple_new_from_data(space, nd, dims, typenum, data, + order='C', owning=False, w_subtype=None): + shape, dtype = get_shape_and_dtype(space, nd, dims, typenum) + storage = rffi.cast(RAW_STORAGE_PTR, data) + if nd == 0: + w_val = dtype.itemtype.box_raw_data(storage) + return W_NDimArray(Scalar(dtype, w_val)) + else: + return W_NDimArray.from_shape_and_storage(space, shape, storage, dtype, + order=order, owning=owning, w_subtype=w_subtype) + + + at cpython_api([Py_ssize_t, rffi.LONGP, Py_ssize_t], PyObject) +def _PyArray_SimpleNew(space, nd, dims, typenum): + return simple_new(space, nd, dims, typenum) + + at cpython_api([Py_ssize_t, rffi.LONGP, Py_ssize_t, rffi.VOIDP], PyObject) +def _PyArray_SimpleNewFromData(space, nd, dims, typenum, data): + return simple_new_from_data(space, nd, dims, typenum, data, owning=False) + + at cpython_api([Py_ssize_t, rffi.LONGP, Py_ssize_t, rffi.VOIDP], PyObject) +def _PyArray_SimpleNewFromDataOwning(space, nd, dims, typenum, data): + # Variant to take over ownership of the memory, equivalent to: + # PyObject *arr = PyArray_SimpleNewFromData(nd, dims, typenum, data); + # ((PyArrayObject*)arr)->flags |= NPY_OWNDATA; + return simple_new_from_data(space, nd, dims, typenum, data, owning=True) + + + at cpython_api([rffi.VOIDP, Py_ssize_t, rffi.LONGP, Py_ssize_t, rffi.LONGP, + rffi.VOIDP, Py_ssize_t, Py_ssize_t, PyObject], PyObject) +def _PyArray_New(space, subtype, nd, dims, typenum, strides, data, itemsize, flags, obj): + if strides: + raise OperationError(space.w_NotImplementedError, + space.wrap("strides must be NULL")) + + order = 'C' if flags & NPY_C_CONTIGUOUS else 'F' + owning = True if flags & NPY_OWNDATA else False + w_subtype = None + + if data: + return simple_new_from_data(space, nd, dims, typenum, data, + order=order, owning=owning, w_subtype=w_subtype) + else: + return simple_new(space, nd, dims, typenum, + order=order, owning=owning, w_subtype=w_subtype) + diff --git a/pypy/module/cpyext/number.py b/pypy/module/cpyext/number.py --- a/pypy/module/cpyext/number.py +++ b/pypy/module/cpyext/number.py @@ -1,8 +1,9 @@ from pypy.interpreter.error import OperationError from pypy.module.cpyext.api import cpython_api, CANNOT_FAIL, Py_ssize_t -from pypy.module.cpyext.pyobject import PyObject +from pypy.module.cpyext.pyobject import PyObject, PyObjectP, from_ref, make_ref, Py_DecRef from rpython.rtyper.lltypesystem import rffi, lltype from rpython.tool.sourcetools import func_with_new_name +from pypy.module.cpyext.state import State @cpython_api([PyObject], rffi.INT_real, error=CANNOT_FAIL) def PyIndex_Check(space, w_obj): @@ -56,6 +57,39 @@ """ return space.index(w_obj) + at cpython_api([PyObjectP, PyObjectP], rffi.INT_real, error=CANNOT_FAIL) +def PyNumber_CoerceEx(space, pp1, pp2): + """This function is similar to PyNumber_Coerce(), except that it returns + 1 when the conversion is not possible and when no error is raised. + Reference counts are still not increased in this case.""" + retVal = PyNumber_Coerce(space, pp1, pp2) + if retVal != 0: + return 1 + return 0 + + at cpython_api([PyObjectP, PyObjectP], rffi.INT_real, error=CANNOT_FAIL) +def PyNumber_Coerce(space, pp1, pp2): + """This function takes the addresses of two variables of type PyObject*. If + the objects pointed to by *p1 and *p2 have the same type, increment their + reference count and return 0 (success). If the objects can be converted to a + common numeric type, replace *p1 and *p2 by their converted value (with + 'new' reference counts), and return 0. If no conversion is possible, or if + some other error occurs, return -1 (failure) and don't increment the + reference counts. The call PyNumber_Coerce(&o1, &o2) is equivalent to the + Python statement o1, o2 = coerce(o1, o2).""" + w_obj1 = from_ref(space, pp1[0]) + w_obj2 = from_ref(space, pp2[0]) + try: + w_res = space.coerce(w_obj1, w_obj2) + except (TypeError, OperationError): + state = space.fromcache(State) + state.clear_exception() + return -1 + w_res1, w_res2 = space.unpackiterable(w_res, 2) + pp1[0] = make_ref(space, w_res1) + pp2[0] = make_ref(space, w_res2) + return 0 + def func_rename(newname): return lambda func: func_with_new_name(func, newname) diff --git a/pypy/module/cpyext/src/missing.c b/pypy/module/cpyext/src/missing.c new file mode 100644 --- /dev/null +++ b/pypy/module/cpyext/src/missing.c @@ -0,0 +1,29 @@ +/* Definitions of missing symbols go here */ + +#include "Python.h" + +PyTypeObject PyFunction_Type; + +PyTypeObject PyMethod_Type; +PyTypeObject PyRange_Type; +PyTypeObject PyTraceBack_Type; + +int Py_DebugFlag = 1; +int Py_VerboseFlag = 0; +int Py_InteractiveFlag = 0; +int Py_InspectFlag = 0; +int Py_OptimizeFlag = 0; +int Py_NoSiteFlag = 0; +int Py_BytesWarningFlag = 0; +int Py_UseClassExceptionsFlag = 0; +int Py_FrozenFlag = 0; +int Py_TabcheckFlag = 0; +int Py_UnicodeFlag = 0; +int Py_IgnoreEnvironmentFlag = 0; +int Py_DivisionWarningFlag = 0; +int Py_DontWriteBytecodeFlag = 0; +int Py_NoUserSiteDirectory = 0; +int _Py_QnewFlag = 0; +int Py_Py3kWarningFlag = 0; +int Py_HashRandomizationFlag = 0; + diff --git a/pypy/module/cpyext/src/modsupport.c b/pypy/module/cpyext/src/modsupport.c --- a/pypy/module/cpyext/src/modsupport.c +++ b/pypy/module/cpyext/src/modsupport.c @@ -8,7 +8,9 @@ static PyObject *va_build_value(const char *, va_list, int); -/* Package context -- the full module name for package imports */ +/* Package context -- the full module name for package imports + * Should this be modified in _Py_InitPyPyModule for CPython + * compatibility (see CPython's Py_InitModule4)? */ char *_Py_PackageContext = NULL; /* Helper for mkvalue() to scan the length of a format */ diff --git a/pypy/module/cpyext/src/ndarrayobject.c b/pypy/module/cpyext/src/ndarrayobject.c new file mode 100644 --- /dev/null +++ b/pypy/module/cpyext/src/ndarrayobject.c @@ -0,0 +1,27 @@ + +#include "Python.h" +#include "numpy/arrayobject.h" +#include /* memset, memcpy */ + +PyTypeObject PyArray_Type; + +void +_PyArray_FILLWBYTE(PyObject* obj, int val) { + memset(PyArray_DATA(obj), val, PyArray_NBYTES(obj)); +} + +PyObject* +_PyArray_ZEROS(int nd, npy_intp* dims, int type_num, int fortran) +{ + PyObject *arr = PyArray_EMPTY(nd, dims, type_num, fortran); + memset(PyArray_DATA(arr), 0, PyArray_NBYTES(arr)); + return arr; +} + +int +_PyArray_CopyInto(PyArrayObject* dest, PyArrayObject* src) +{ + memcpy(PyArray_DATA(dest), PyArray_DATA(src), PyArray_NBYTES(dest)); + return 0; +} + diff --git a/pypy/module/cpyext/test/test_api.py b/pypy/module/cpyext/test/test_api.py --- a/pypy/module/cpyext/test/test_api.py +++ b/pypy/module/cpyext/test/test_api.py @@ -46,7 +46,7 @@ raise Exception("DID NOT RAISE") if getattr(space, 'w_' + expected_exc.__name__) is not operror.w_type: raise Exception("Wrong exception") - state.clear_exception() + return state.clear_exception() def setup_method(self, func): freeze_refcnts(self) diff --git a/pypy/module/cpyext/test/test_ndarrayobject.py b/pypy/module/cpyext/test/test_ndarrayobject.py new file mode 100644 --- /dev/null +++ b/pypy/module/cpyext/test/test_ndarrayobject.py @@ -0,0 +1,279 @@ +import py + +from pypy.module.cpyext.test.test_api import BaseApiTest +from pypy.module.cpyext.test.test_cpyext import AppTestCpythonExtensionBase +from rpython.rtyper.lltypesystem import rffi, lltype + +from pypy.module.micronumpy.interp_numarray import W_NDimArray +from pypy.module.micronumpy.interp_dtype import get_dtype_cache + +def scalar(space): + dtype = get_dtype_cache(space).w_float64dtype + return W_NDimArray.new_scalar(space, dtype, space.wrap(10.)) + +def array(space, shape, order='C'): + dtype = get_dtype_cache(space).w_float64dtype + return W_NDimArray.from_shape(space, shape, dtype, order=order) + +def iarray(space, shape, order='C'): + dtype = get_dtype_cache(space).w_int64dtype + return W_NDimArray.from_shape(space, shape, dtype, order=order) + + +NULL = lltype.nullptr(rffi.VOIDP.TO) + +class TestNDArrayObject(BaseApiTest): + + def test_Check(self, space, api): + a = array(space, [10, 5, 3]) + x = space.wrap(10.) + assert api._PyArray_Check(a) + assert api._PyArray_CheckExact(a) + assert not api._PyArray_Check(x) + assert not api._PyArray_CheckExact(x) + + def test_FLAGS(self, space, api): + s = array(space, [10]) + c = array(space, [10, 5, 3], order='C') + f = array(space, [10, 5, 3], order='F') + assert api._PyArray_FLAGS(s) & 0x0001 + assert api._PyArray_FLAGS(s) & 0x0002 + assert api._PyArray_FLAGS(c) & 0x0001 + assert api._PyArray_FLAGS(f) & 0x0002 + assert not api._PyArray_FLAGS(c) & 0x0002 + assert not api._PyArray_FLAGS(f) & 0x0001 + + def test_NDIM(self, space, api): + a = array(space, [10, 5, 3]) + assert api._PyArray_NDIM(a) == 3 + + def test_DIM(self, space, api): + a = array(space, [10, 5, 3]) + assert api._PyArray_DIM(a, 1) == 5 + + def test_STRIDE(self, space, api): + a = array(space, [10, 5, 3], ) + assert api._PyArray_STRIDE(a, 1) == a.implementation.get_strides()[1] + + def test_SIZE(self, space, api): + a = array(space, [10, 5, 3]) + assert api._PyArray_SIZE(a) == 150 + + def test_ITEMSIZE(self, space, api): + a = array(space, [10, 5, 3]) + assert api._PyArray_ITEMSIZE(a) == 8 + + def test_NBYTES(self, space, api): + a = array(space, [10, 5, 3]) + assert api._PyArray_NBYTES(a) == 1200 + + def test_TYPE(self, space, api): + a = array(space, [10, 5, 3]) + assert api._PyArray_TYPE(a) == 12 + + def test_DATA(self, space, api): + a = array(space, [10, 5, 3]) + addr = api._PyArray_DATA(a) + addr2 = rffi.cast(rffi.VOIDP, a.implementation.storage) + assert addr == addr2 + + def test_FromAny_scalar(self, space, api): + a0 = scalar(space) + assert a0.implementation.get_scalar_value().value == 10. + + a = api._PyArray_FromAny(a0, NULL, 0, 0, 0, NULL) + assert api._PyArray_NDIM(a) == 0 + + ptr = rffi.cast(rffi.DOUBLEP, api._PyArray_DATA(a)) + assert ptr[0] == 10. + + def test_FromAny(self, space, api): + a = array(space, [10, 5, 3]) + assert api._PyArray_FromAny(a, NULL, 0, 0, 0, NULL) is a + self.raises(space, api, NotImplementedError, api._PyArray_FromAny, + a, NULL, 0, 3, 0, NULL) + + def test_FromObject(self, space, api): + a = array(space, [10, 5, 3]) + assert api._PyArray_FromObject(a, a.get_dtype().num, 0, 0) is a + exc = self.raises(space, api, NotImplementedError, api._PyArray_FromObject, + a, 11, 0, 3) + assert exc.errorstr(space).find('FromObject') >= 0 + + def test_list_from_fixedptr(self, space, api): + A = lltype.GcArray(lltype.Float) + ptr = lltype.malloc(A, 3) + assert isinstance(ptr, lltype._ptr) + ptr[0] = 10. + ptr[1] = 5. + ptr[2] = 3. + l = list(ptr) + assert l == [10., 5., 3.] + + def test_list_from_openptr(self, space, api): + nd = 3 + a = array(space, [nd]) + ptr = rffi.cast(rffi.DOUBLEP, api._PyArray_DATA(a)) + ptr[0] = 10. + ptr[1] = 5. + ptr[2] = 3. + l = [] + for i in range(nd): + l.append(ptr[i]) + assert l == [10., 5., 3.] + + def test_SimpleNew_scalar(self, space, api): + ptr_s = lltype.nullptr(rffi.LONGP.TO) + a = api._PyArray_SimpleNew(0, ptr_s, 12) + + dtype = get_dtype_cache(space).w_float64dtype + + a.set_scalar_value(dtype.itemtype.box(10.)) + assert a.get_scalar_value().value == 10. + + def test_SimpleNewFromData_scalar(self, space, api): + a = array(space, [1]) + num = api._PyArray_TYPE(a) + ptr_a = api._PyArray_DATA(a) + + x = rffi.cast(rffi.DOUBLEP, ptr_a) + x[0] = float(10.) + + ptr_s = lltype.nullptr(rffi.LONGP.TO) + + res = api._PyArray_SimpleNewFromData(0, ptr_s, num, ptr_a) + assert res.is_scalar() + assert res.get_scalar_value().value == 10. + + def test_SimpleNew(self, space, api): + shape = [10, 5, 3] + nd = len(shape) + + s = iarray(space, [nd]) + ptr_s = rffi.cast(rffi.LONGP, api._PyArray_DATA(s)) + ptr_s[0] = 10 + ptr_s[1] = 5 + ptr_s[2] = 3 + + a = api._PyArray_SimpleNew(nd, ptr_s, 12) + + #assert list(api._PyArray_DIMS(a))[:3] == shape + + ptr_a = api._PyArray_DATA(a) + + x = rffi.cast(rffi.DOUBLEP, ptr_a) + for i in range(150): + x[i] = float(i) + + for i in range(150): + assert x[i] == float(i) + + def test_SimpleNewFromData(self, space, api): + shape = [10, 5, 3] + nd = len(shape) + + s = iarray(space, [nd]) + ptr_s = rffi.cast(rffi.LONGP, api._PyArray_DATA(s)) + ptr_s[0] = 10 + ptr_s[1] = 5 + ptr_s[2] = 3 + + a = array(space, shape) + num = api._PyArray_TYPE(a) + ptr_a = api._PyArray_DATA(a) + + x = rffi.cast(rffi.DOUBLEP, ptr_a) + for i in range(150): + x[i] = float(i) + + res = api._PyArray_SimpleNewFromData(nd, ptr_s, num, ptr_a) + assert api._PyArray_TYPE(res) == num + assert api._PyArray_DATA(res) == ptr_a + for i in range(nd): + assert api._PyArray_DIM(res, i) == shape[i] + ptr_r = rffi.cast(rffi.DOUBLEP, api._PyArray_DATA(res)) + for i in range(150): + assert ptr_r[i] == float(i) + res = api._PyArray_SimpleNewFromDataOwning(nd, ptr_s, num, ptr_a) + x = rffi.cast(rffi.DOUBLEP, ptr_a) + ptr_r = rffi.cast(rffi.DOUBLEP, api._PyArray_DATA(res)) + x[20] = -100. + assert ptr_r[20] == -100. + + def test_SimpleNewFromData_complex(self, space, api): + a = array(space, [2]) + ptr_a = api._PyArray_DATA(a) + + x = rffi.cast(rffi.DOUBLEP, ptr_a) + x[0] = 3. + x[1] = 4. + + ptr_s = lltype.nullptr(rffi.LONGP.TO) + + res = api._PyArray_SimpleNewFromData(0, ptr_s, 15, ptr_a) + assert res.get_scalar_value().real == 3. + assert res.get_scalar_value().imag == 4. + +class AppTestCNumber(AppTestCpythonExtensionBase): + def test_ndarray_object_c(self): + mod = self.import_extension('foo', [ + ("test_simplenew", "METH_NOARGS", + ''' + npy_intp dims[2] ={2, 3}; + PyObject * obj = PyArray_SimpleNew(2, dims, 11); + return obj; + ''' + ), + ("test_fill", "METH_NOARGS", + ''' + npy_intp dims[2] ={2, 3}; + PyObject * obj = PyArray_SimpleNew(2, dims, 1); + PyArray_FILLWBYTE(obj, 42); + return obj; + ''' + ), + ("test_copy", "METH_NOARGS", + ''' + npy_intp dims1[2] ={2, 3}; + npy_intp dims2[2] ={3, 2}; + PyObject * obj1 = PyArray_ZEROS(2, dims1, 11, 0); + PyObject * obj2 = PyArray_ZEROS(2, dims2, 11, 0); + PyArray_FILLWBYTE(obj2, 42); + PyArray_CopyInto(obj2, obj1); + Py_DECREF(obj1); + return obj2; + ''' + ), + ("test_FromAny", "METH_NOARGS", + ''' + npy_intp dims[2] ={2, 3}; + PyObject * obj1 = PyArray_SimpleNew(2, dims, 1); + PyArray_FILLWBYTE(obj1, 42); + PyObject * obj2 = _PyArray_FromAny(obj1, NULL, 0, 0, 0, NULL); + Py_DECREF(obj1); + return obj2; + ''' + ), + ("test_FromObject", "METH_NOARGS", + ''' + npy_intp dims[2] ={2, 3}; + PyObject * obj1 = PyArray_SimpleNew(2, dims, 1); + PyArray_FILLWBYTE(obj1, 42); + PyObject * obj2 = _PyArray_FromObject(obj1, 12, 0, 0); + Py_DECREF(obj1); + return obj2; + ''' + ), + ], prologue='#include ') + arr = mod.test_simplenew() + assert arr.shape == (2, 3) + assert arr.dtype.num == 11 #float32 dtype + arr = mod.test_fill() + assert arr.shape == (2, 3) + assert arr.dtype.num == 1 #int8 dtype + assert (arr == 42).all() + arr = mod.test_copy() + assert (arr == 0).all() + #Make sure these work without errors + arr = mod.test_FromAny() + arr = mod.test_FromObject() diff --git a/pypy/module/cpyext/test/test_number.py b/pypy/module/cpyext/test/test_number.py --- a/pypy/module/cpyext/test/test_number.py +++ b/pypy/module/cpyext/test/test_number.py @@ -1,7 +1,7 @@ -from rpython.rtyper.lltypesystem import rffi, lltype -from pypy.interpreter.error import OperationError +from rpython.rtyper.lltypesystem import lltype from pypy.module.cpyext.test.test_api import BaseApiTest -from pypy.module.cpyext import sequence +from pypy.module.cpyext.pyobject import PyObjectP, from_ref, make_ref, Py_DecRef +from pypy.module.cpyext.test.test_cpyext import AppTestCpythonExtensionBase class TestIterator(BaseApiTest): def test_check(self, space, api): @@ -39,6 +39,46 @@ assert w_l is None api.PyErr_Clear() + def test_coerce(self, space, api): + w_obj1 = space.wrap(123) + w_obj2 = space.wrap(456.789) + pp1 = lltype.malloc(PyObjectP.TO, 1, flavor='raw') + pp1[0] = make_ref(space, w_obj1) + pp2 = lltype.malloc(PyObjectP.TO, 1, flavor='raw') + pp2[0] = make_ref(space, w_obj2) + assert api.PyNumber_Coerce(pp1, pp2) == 0 + assert space.str_w(space.repr(from_ref(space, pp1[0]))) == '123.0' + assert space.str_w(space.repr(from_ref(space, pp2[0]))) == '456.789' + Py_DecRef(space, pp1[0]) + Py_DecRef(space, pp2[0]) + lltype.free(pp1, flavor='raw') + # Yes, decrement twice since we decoupled between w_obj* and pp*[0]. + Py_DecRef(space, w_obj1) + Py_DecRef(space, w_obj2) + lltype.free(pp2, flavor='raw') + + def test_number_coerce_ex(self, space, api): + pl = make_ref(space, space.wrap(123)) + pf = make_ref(space, space.wrap(42.)) + ppl = lltype.malloc(PyObjectP.TO, 1, flavor='raw') + ppf = lltype.malloc(PyObjectP.TO, 1, flavor='raw') + ppl[0] = pl + ppf[0] = pf + + ret = api.PyNumber_CoerceEx(ppl, ppf) + assert ret == 0 + + w_res = from_ref(space, ppl[0]) + + assert api.PyFloat_Check(w_res) + assert space.unwrap(w_res) == 123. + Py_DecRef(space, pl) + Py_DecRef(space, pf) + Py_DecRef(space, ppl[0]) + Py_DecRef(space, ppf[0]) + lltype.free(ppl, flavor='raw') + lltype.free(ppf, flavor='raw') + def test_numbermethods(self, space, api): assert "ab" == space.unwrap( api.PyNumber_Add(space.wrap("a"), space.wrap("b"))) @@ -64,3 +104,40 @@ api.PyNumber_Power(space.wrap(3), space.wrap(2), space.wrap(5))) assert 9 == space.unwrap( api.PyNumber_InPlacePower(space.wrap(3), space.wrap(2), space.w_None)) + +class AppTestCNumber(AppTestCpythonExtensionBase): + def test_app_coerce(self): + mod = self.import_extension('foo', [ + ("test_fail", "METH_NOARGS", + ''' + PyObject * hello = PyString_FromString("hello"); + PyObject * float1 = PyFloat_FromDouble(1.0); + int retVal = PyNumber_Coerce(&hello, &float1); + Py_DECREF(hello); + Py_DECREF(float1); + return PyInt_FromLong(retVal); + '''), + ("test", "METH_NOARGS", + ''' + PyObject * float1p = PyFloat_FromDouble(1.0); + PyObject * int3p = PyInt_FromLong(3); + PyObject * tupl = PyTuple_New(2); + PyObject float1 = *float1p; + PyObject int3 = *int3p; + int retVal = PyNumber_CoerceEx(&int3p, &float1p); From noreply at buildbot.pypy.org Sat Sep 28 00:43:03 2013 From: noreply at buildbot.pypy.org (pjenvey) Date: Sat, 28 Sep 2013 00:43:03 +0200 (CEST) Subject: [pypy-commit] pypy py3k: merge upstream Message-ID: <20130927224303.945B21C087E@cobra.cs.uni-duesseldorf.de> Author: Philip Jenvey Branch: py3k Changeset: r67121:1304757e1917 Date: 2013-09-27 15:27 -0700 http://bitbucket.org/pypy/pypy/changeset/1304757e1917/ Log: merge upstream diff --git a/lib_pypy/pyrepl/readline.py b/lib_pypy/pyrepl/readline.py --- a/lib_pypy/pyrepl/readline.py +++ b/lib_pypy/pyrepl/readline.py @@ -422,7 +422,7 @@ del sys.__raw_input__ except AttributeError: pass - return raw_input(prompt) + return input(prompt) sys.__raw_input__ = _wrapper.raw_input else: From noreply at buildbot.pypy.org Sat Sep 28 00:43:04 2013 From: noreply at buildbot.pypy.org (pjenvey) Date: Sat, 28 Sep 2013 00:43:04 +0200 (CEST) Subject: [pypy-commit] pypy py3k: n/a on py3k Message-ID: <20130927224304.CEDCD1C087E@cobra.cs.uni-duesseldorf.de> Author: Philip Jenvey Branch: py3k Changeset: r67122:d01614e0de3a Date: 2013-09-27 15:28 -0700 http://bitbucket.org/pypy/pypy/changeset/d01614e0de3a/ Log: n/a on py3k 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 @@ -47,11 +47,6 @@ # XXX: broken #assert True.__int__() is 1 - def test_bool_long(self): - assert long(True) is 1L - assert long(False) is 0L - assert True.__long__() is 1L - def test_bool_ops(self): assert True + True == 2 assert False | False is False From noreply at buildbot.pypy.org Sat Sep 28 00:43:06 2013 From: noreply at buildbot.pypy.org (pjenvey) Date: Sat, 28 Sep 2013 00:43:06 +0200 (CEST) Subject: [pypy-commit] pypy py3k: update to 3.2.3's prototypes Message-ID: <20130927224306.044DB1C087E@cobra.cs.uni-duesseldorf.de> Author: Philip Jenvey Branch: py3k Changeset: r67123:5309efa2f521 Date: 2013-09-27 15:42 -0700 http://bitbucket.org/pypy/pypy/changeset/5309efa2f521/ Log: update to 3.2.3's prototypes diff --git a/pypy/module/cpyext/include/pythonrun.h b/pypy/module/cpyext/include/pythonrun.h --- a/pypy/module/cpyext/include/pythonrun.h +++ b/pypy/module/cpyext/include/pythonrun.h @@ -8,9 +8,10 @@ PyAPI_FUNC(void) Py_FatalError(const char *message); -/* taken from Python-2.7.3/Include/pydebug.h */ +/* taken from Python-3.2.3/Include/pydebug.h */ PyAPI_DATA(int) Py_DebugFlag; PyAPI_DATA(int) Py_VerboseFlag; +PyAPI_DATA(int) Py_QuietFlag; PyAPI_DATA(int) Py_InteractiveFlag; PyAPI_DATA(int) Py_InspectFlag; PyAPI_DATA(int) Py_OptimizeFlag; @@ -18,18 +19,11 @@ PyAPI_DATA(int) Py_BytesWarningFlag; PyAPI_DATA(int) Py_UseClassExceptionsFlag; PyAPI_DATA(int) Py_FrozenFlag; -PyAPI_DATA(int) Py_TabcheckFlag; -PyAPI_DATA(int) Py_UnicodeFlag; PyAPI_DATA(int) Py_IgnoreEnvironmentFlag; PyAPI_DATA(int) Py_DivisionWarningFlag; PyAPI_DATA(int) Py_DontWriteBytecodeFlag; PyAPI_DATA(int) Py_NoUserSiteDirectory; -/* _XXX Py_QnewFlag should go away in 3.0. It's true iff -Qnew is passed, - * on the command line, and is used in 2.2 by ceval.c to make all "/" divisions - * true divisions (which they will be in 3.0). */ -PyAPI_DATA(int) _Py_QnewFlag; -/* Warn about 3.x issues */ -PyAPI_DATA(int) Py_Py3kWarningFlag; +PyAPI_DATA(int) Py_UnbufferedStdioFlag; PyAPI_DATA(int) Py_HashRandomizationFlag; From noreply at buildbot.pypy.org Sat Sep 28 13:57:48 2013 From: noreply at buildbot.pypy.org (bivab) Date: Sat, 28 Sep 2013 13:57:48 +0200 (CEST) Subject: [pypy-commit] pypy default: _sqlite3.connect accepts positional arguments. Copy the interface of Connection.__init__ :/ Message-ID: <20130928115748.82EC81C1361@cobra.cs.uni-duesseldorf.de> Author: David Schneider Branch: Changeset: r67124:c9f9979e0eed Date: 2013-09-28 13:57 +0200 http://bitbucket.org/pypy/pypy/changeset/c9f9979e0eed/ Log: _sqlite3.connect accepts positional arguments. Copy the interface of Connection.__init__ :/ diff --git a/lib_pypy/_sqlite3.py b/lib_pypy/_sqlite3.py --- a/lib_pypy/_sqlite3.py +++ b/lib_pypy/_sqlite3.py @@ -363,9 +363,11 @@ pass -def connect(database, **kwargs): - factory = kwargs.get("factory", Connection) - return factory(database, **kwargs) +def connect(database, timeout=5.0, detect_types=0, isolation_level="", + check_same_thread=True, factory=None, cached_statements=100): + factory = Connection if not factory else factory + return factory(database, timeout, detect_types, isolation_level, + check_same_thread, factory, cached_statements) def _unicode_text_factory(x): 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 @@ -31,6 +31,12 @@ result = list(cursor) assert result == [(42,)] +def test_connect_takes_same_positional_args_as_Connection(con): + from inspect import getargspec + clsargs = getargspec(_sqlite3.Connection.__init__).args[1:] # ignore self + conargs = getargspec(_sqlite3.connect).args + assert clsargs == conargs + def test_total_changes_after_close(con): con.close() pytest.raises(_sqlite3.ProgrammingError, "con.total_changes") From noreply at buildbot.pypy.org Sat Sep 28 18:55:53 2013 From: noreply at buildbot.pypy.org (arigo) Date: Sat, 28 Sep 2013 18:55:53 +0200 (CEST) Subject: [pypy-commit] pypy default: (amaury on issue 1616) Message-ID: <20130928165553.8D98B1C0934@cobra.cs.uni-duesseldorf.de> Author: Armin Rigo Branch: Changeset: r67125:662603ceb3a5 Date: 2013-09-28 18:55 +0200 http://bitbucket.org/pypy/pypy/changeset/662603ceb3a5/ Log: (amaury on issue 1616) Fix for some missing cases. diff --git a/lib_pypy/_tkinter/tclobj.py b/lib_pypy/_tkinter/tclobj.py --- a/lib_pypy/_tkinter/tclobj.py +++ b/lib_pypy/_tkinter/tclobj.py @@ -28,9 +28,11 @@ return result elif value.typePtr == typeCache.BooleanType: - return result + return bool(value.internalRep.longValue) elif value.typePtr == typeCache.ByteArrayType: - return result + size = tkffi.new('int*') + data = tklib.Tcl_GetByteArrayFromObj(value, size) + return tkffi.buffer(data, size[0])[:] elif value.typePtr == typeCache.DoubleType: return value.internalRep.doubleValue elif value.typePtr == typeCache.IntType: @@ -50,7 +52,7 @@ result.append(FromObj(app, tcl_elem[0])) return tuple(result) elif value.typePtr == typeCache.ProcBodyType: - return result + pass # fall through and return tcl object. elif value.typePtr == typeCache.StringType: buf = tklib.Tcl_GetUnicode(value) length = tklib.Tcl_GetCharLength(value) From noreply at buildbot.pypy.org Sat Sep 28 20:18:57 2013 From: noreply at buildbot.pypy.org (arigo) Date: Sat, 28 Sep 2013 20:18:57 +0200 (CEST) Subject: [pypy-commit] pypy default: Add a link to the regular list of dependencies. Message-ID: <20130928181857.1E9C11C0934@cobra.cs.uni-duesseldorf.de> Author: Armin Rigo Branch: Changeset: r67126:53a8307f63aa Date: 2013-09-28 20:18 +0200 http://bitbucket.org/pypy/pypy/changeset/53a8307f63aa/ Log: Add a link to the regular list of dependencies. diff --git a/pypy/doc/arm.rst b/pypy/doc/arm.rst --- a/pypy/doc/arm.rst +++ b/pypy/doc/arm.rst @@ -35,6 +35,11 @@ * ``qemu-system`` * ``qemu-user-static`` +- The dependencies above are in addition to the ones needed for a regular + translation, `listed here`_. + +.. _`listed here`: getting-started-python.html#translating-the-pypy-python-interpreter + Creating a Qemu based ARM chroot -------------------------------- From noreply at buildbot.pypy.org Sat Sep 28 20:23:17 2013 From: noreply at buildbot.pypy.org (amauryfa) Date: Sat, 28 Sep 2013 20:23:17 +0200 (CEST) Subject: [pypy-commit] pypy default: Another blind fix, needed by 662603ceb3a5 Message-ID: <20130928182317.1F3C71C1361@cobra.cs.uni-duesseldorf.de> Author: Amaury Forgeot d'Arc Branch: Changeset: r67127:c48e4a735c9a Date: 2013-09-28 20:22 +0200 http://bitbucket.org/pypy/pypy/changeset/c48e4a735c9a/ Log: Another blind fix, needed by 662603ceb3a5 diff --git a/lib_pypy/_tkinter/tklib.py b/lib_pypy/_tkinter/tklib.py --- a/lib_pypy/_tkinter/tklib.py +++ b/lib_pypy/_tkinter/tklib.py @@ -72,6 +72,7 @@ int Tcl_GetBoolean(Tcl_Interp* interp, const char* src, int* boolPtr); char *Tcl_GetString(Tcl_Obj* objPtr); char *Tcl_GetStringFromObj(Tcl_Obj* objPtr, int* lengthPtr); +unsigned char *Tcl_GetByteArrayFromObj(Tcl_Obj* objPtr, int* lengthPtr); Tcl_UniChar *Tcl_GetUnicode(Tcl_Obj* objPtr); int Tcl_GetCharLength(Tcl_Obj* objPtr); From noreply at buildbot.pypy.org Sun Sep 29 00:37:48 2013 From: noreply at buildbot.pypy.org (alex_gaynor) Date: Sun, 29 Sep 2013 00:37:48 +0200 (CEST) Subject: [pypy-commit] pypy default: int_sub(x, x) -> 0 Message-ID: <20130928223748.BC2851C34D9@cobra.cs.uni-duesseldorf.de> Author: Alex Gaynor Branch: Changeset: r67128:410b98e96c08 Date: 2013-09-28 15:37 -0700 http://bitbucket.org/pypy/pypy/changeset/410b98e96c08/ Log: int_sub(x, x) -> 0 diff --git a/rpython/jit/metainterp/optimizeopt/rewrite.py b/rpython/jit/metainterp/optimizeopt/rewrite.py --- a/rpython/jit/metainterp/optimizeopt/rewrite.py +++ b/rpython/jit/metainterp/optimizeopt/rewrite.py @@ -107,6 +107,8 @@ v2 = self.getvalue(op.getarg(1)) if v2.is_constant() and v2.box.getint() == 0: self.make_equal_to(op.result, v1) + elif v1 is v2: + self.make_constant_int(op.result, 0) else: self.emit_operation(op) # Synthesize the reverse ops for optimize_default to reuse diff --git a/rpython/jit/metainterp/optimizeopt/test/test_optimizebasic.py b/rpython/jit/metainterp/optimizeopt/test/test_optimizebasic.py --- a/rpython/jit/metainterp/optimizeopt/test/test_optimizebasic.py +++ b/rpython/jit/metainterp/optimizeopt/test/test_optimizebasic.py @@ -3735,6 +3735,18 @@ """ self.optimize_loop(ops, expected) + def test_sub_identity(self): + ops = """ + [i0] + i1 = int_sub(i0, i0) + jump(i1) + """ + expected = """ + [i0] + jump(0) + """ + self.optimize_loop(ops, expected) + def test_bound_and(self): ops = """ [i0] From noreply at buildbot.pypy.org Sun Sep 29 00:47:43 2013 From: noreply at buildbot.pypy.org (alex_gaynor) Date: Sun, 29 Sep 2013 00:47:43 +0200 (CEST) Subject: [pypy-commit] pypy default: int_sub(0, x) -> int_neg(x) Message-ID: <20130928224743.968831C34D9@cobra.cs.uni-duesseldorf.de> Author: Alex Gaynor Branch: Changeset: r67129:ef1fb51633c3 Date: 2013-09-28 15:47 -0700 http://bitbucket.org/pypy/pypy/changeset/ef1fb51633c3/ Log: int_sub(0, x) -> int_neg(x) diff --git a/rpython/jit/metainterp/optimizeopt/rewrite.py b/rpython/jit/metainterp/optimizeopt/rewrite.py --- a/rpython/jit/metainterp/optimizeopt/rewrite.py +++ b/rpython/jit/metainterp/optimizeopt/rewrite.py @@ -107,6 +107,9 @@ v2 = self.getvalue(op.getarg(1)) if v2.is_constant() and v2.box.getint() == 0: self.make_equal_to(op.result, v1) + elif v1.is_constant() and v1.box.getint() == 0: + op = op.copy_and_change(rop.INT_NEG, args=[v2.box]) + self.emit_operation(op) elif v1 is v2: self.make_constant_int(op.result, 0) else: diff --git a/rpython/jit/metainterp/optimizeopt/test/test_optimizebasic.py b/rpython/jit/metainterp/optimizeopt/test/test_optimizebasic.py --- a/rpython/jit/metainterp/optimizeopt/test/test_optimizebasic.py +++ b/rpython/jit/metainterp/optimizeopt/test/test_optimizebasic.py @@ -3739,11 +3739,13 @@ ops = """ [i0] i1 = int_sub(i0, i0) - jump(i1) + i2 = int_sub(i1, i0) + jump(i1, i2) """ expected = """ [i0] - jump(0) + i2 = int_neg(i0) + jump(0, i2) """ self.optimize_loop(ops, expected) From noreply at buildbot.pypy.org Sun Sep 29 01:01:23 2013 From: noreply at buildbot.pypy.org (pjenvey) Date: Sun, 29 Sep 2013 01:01:23 +0200 (CEST) Subject: [pypy-commit] pypy py3k: rekill coerce Message-ID: <20130928230123.19AB21C34D9@cobra.cs.uni-duesseldorf.de> Author: Philip Jenvey Branch: py3k Changeset: r67130:178720ddcb24 Date: 2013-09-28 16:00 -0700 http://bitbucket.org/pypy/pypy/changeset/178720ddcb24/ Log: rekill coerce diff --git a/pypy/module/cpyext/number.py b/pypy/module/cpyext/number.py --- a/pypy/module/cpyext/number.py +++ b/pypy/module/cpyext/number.py @@ -1,9 +1,8 @@ from pypy.interpreter.error import OperationError from pypy.module.cpyext.api import cpython_api, CANNOT_FAIL, Py_ssize_t -from pypy.module.cpyext.pyobject import PyObject, PyObjectP, from_ref, make_ref, Py_DecRef +from pypy.module.cpyext.pyobject import PyObject from rpython.rtyper.lltypesystem import rffi, lltype from rpython.tool.sourcetools import func_with_new_name -from pypy.module.cpyext.state import State @cpython_api([PyObject], rffi.INT_real, error=CANNOT_FAIL) def PyIndex_Check(space, w_obj): @@ -57,39 +56,6 @@ """ return space.index(w_obj) - at cpython_api([PyObjectP, PyObjectP], rffi.INT_real, error=CANNOT_FAIL) -def PyNumber_CoerceEx(space, pp1, pp2): - """This function is similar to PyNumber_Coerce(), except that it returns - 1 when the conversion is not possible and when no error is raised. - Reference counts are still not increased in this case.""" - retVal = PyNumber_Coerce(space, pp1, pp2) - if retVal != 0: - return 1 - return 0 - - at cpython_api([PyObjectP, PyObjectP], rffi.INT_real, error=CANNOT_FAIL) -def PyNumber_Coerce(space, pp1, pp2): - """This function takes the addresses of two variables of type PyObject*. If - the objects pointed to by *p1 and *p2 have the same type, increment their - reference count and return 0 (success). If the objects can be converted to a - common numeric type, replace *p1 and *p2 by their converted value (with - 'new' reference counts), and return 0. If no conversion is possible, or if - some other error occurs, return -1 (failure) and don't increment the - reference counts. The call PyNumber_Coerce(&o1, &o2) is equivalent to the - Python statement o1, o2 = coerce(o1, o2).""" - w_obj1 = from_ref(space, pp1[0]) - w_obj2 = from_ref(space, pp2[0]) - try: - w_res = space.coerce(w_obj1, w_obj2) - except (TypeError, OperationError): - state = space.fromcache(State) - state.clear_exception() - return -1 - w_res1, w_res2 = space.unpackiterable(w_res, 2) - pp1[0] = make_ref(space, w_res1) - pp2[0] = make_ref(space, w_res2) - return 0 - def func_rename(newname): return lambda func: func_with_new_name(func, newname) diff --git a/pypy/module/cpyext/test/test_number.py b/pypy/module/cpyext/test/test_number.py --- a/pypy/module/cpyext/test/test_number.py +++ b/pypy/module/cpyext/test/test_number.py @@ -1,7 +1,5 @@ from rpython.rtyper.lltypesystem import lltype from pypy.module.cpyext.test.test_api import BaseApiTest -from pypy.module.cpyext.pyobject import PyObjectP, from_ref, make_ref, Py_DecRef -from pypy.module.cpyext.test.test_cpyext import AppTestCpythonExtensionBase class TestIterator(BaseApiTest): def test_check(self, space, api): @@ -39,46 +37,6 @@ assert w_l is None api.PyErr_Clear() - def test_coerce(self, space, api): - w_obj1 = space.wrap(123) - w_obj2 = space.wrap(456.789) - pp1 = lltype.malloc(PyObjectP.TO, 1, flavor='raw') - pp1[0] = make_ref(space, w_obj1) - pp2 = lltype.malloc(PyObjectP.TO, 1, flavor='raw') - pp2[0] = make_ref(space, w_obj2) - assert api.PyNumber_Coerce(pp1, pp2) == 0 - assert space.str_w(space.repr(from_ref(space, pp1[0]))) == '123.0' - assert space.str_w(space.repr(from_ref(space, pp2[0]))) == '456.789' - Py_DecRef(space, pp1[0]) - Py_DecRef(space, pp2[0]) - lltype.free(pp1, flavor='raw') - # Yes, decrement twice since we decoupled between w_obj* and pp*[0]. - Py_DecRef(space, w_obj1) - Py_DecRef(space, w_obj2) - lltype.free(pp2, flavor='raw') - - def test_number_coerce_ex(self, space, api): - pl = make_ref(space, space.wrap(123)) - pf = make_ref(space, space.wrap(42.)) - ppl = lltype.malloc(PyObjectP.TO, 1, flavor='raw') - ppf = lltype.malloc(PyObjectP.TO, 1, flavor='raw') - ppl[0] = pl - ppf[0] = pf - - ret = api.PyNumber_CoerceEx(ppl, ppf) - assert ret == 0 - - w_res = from_ref(space, ppl[0]) - - assert api.PyFloat_Check(w_res) - assert space.unwrap(w_res) == 123. - Py_DecRef(space, pl) - Py_DecRef(space, pf) - Py_DecRef(space, ppl[0]) - Py_DecRef(space, ppf[0]) - lltype.free(ppl, flavor='raw') - lltype.free(ppf, flavor='raw') - def test_numbermethods(self, space, api): assert "ab" == space.unwrap( api.PyNumber_Add(space.wrap("a"), space.wrap("b"))) @@ -104,40 +62,3 @@ api.PyNumber_Power(space.wrap(3), space.wrap(2), space.wrap(5))) assert 9 == space.unwrap( api.PyNumber_InPlacePower(space.wrap(3), space.wrap(2), space.w_None)) - -class AppTestCNumber(AppTestCpythonExtensionBase): - def test_app_coerce(self): - mod = self.import_extension('foo', [ - ("test_fail", "METH_NOARGS", - ''' - PyObject * hello = PyString_FromString("hello"); - PyObject * float1 = PyFloat_FromDouble(1.0); - int retVal = PyNumber_Coerce(&hello, &float1); - Py_DECREF(hello); - Py_DECREF(float1); - return PyInt_FromLong(retVal); - '''), - ("test", "METH_NOARGS", - ''' - PyObject * float1p = PyFloat_FromDouble(1.0); - PyObject * int3p = PyInt_FromLong(3); - PyObject * tupl = PyTuple_New(2); - PyObject float1 = *float1p; - PyObject int3 = *int3p; - int retVal = PyNumber_CoerceEx(&int3p, &float1p); - if (retVal == 0) - { - PyTuple_SET_ITEM(tupl, 0, int3p); - PyTuple_SET_ITEM(tupl, 1, float1p); - } - Py_DECREF(&int3); - Py_DECREF(&float1); - Py_DECREF(int3p); - Py_DECREF(float1p); - return tupl; - ''')]) - assert mod.test_fail() == -1 - '''tupl = mod.test() - assert tupl[0] == 3. - assert tupl[1] == 1. - assert isinstance(tupl[0], float)''' From noreply at buildbot.pypy.org Sun Sep 29 01:33:02 2013 From: noreply at buildbot.pypy.org (alex_gaynor) Date: Sun, 29 Sep 2013 01:33:02 +0200 (CEST) Subject: [pypy-commit] pypy default: int_lshift(0, x) -> 0 Message-ID: <20130928233302.5D04A1C073E@cobra.cs.uni-duesseldorf.de> Author: Alex Gaynor Branch: Changeset: r67131:b6009ce47b65 Date: 2013-09-28 16:32 -0700 http://bitbucket.org/pypy/pypy/changeset/b6009ce47b65/ Log: int_lshift(0, x) -> 0 int_rshift(0, x) -> 0 diff --git a/rpython/jit/metainterp/optimizeopt/rewrite.py b/rpython/jit/metainterp/optimizeopt/rewrite.py --- a/rpython/jit/metainterp/optimizeopt/rewrite.py +++ b/rpython/jit/metainterp/optimizeopt/rewrite.py @@ -171,6 +171,8 @@ if v2.is_constant() and v2.box.getint() == 0: self.make_equal_to(op.result, v1) + elif v1.is_constant() and v1.box.getint() == 0: + self.make_constant_int(op.result, 0) else: self.emit_operation(op) @@ -180,6 +182,8 @@ if v2.is_constant() and v2.box.getint() == 0: self.make_equal_to(op.result, v1) + elif v1.is_constant() and v1.box.getint() == 0: + self.make_constant_int(op.result, 0) else: self.emit_operation(op) diff --git a/rpython/jit/metainterp/optimizeopt/test/test_optimizebasic.py b/rpython/jit/metainterp/optimizeopt/test/test_optimizebasic.py --- a/rpython/jit/metainterp/optimizeopt/test/test_optimizebasic.py +++ b/rpython/jit/metainterp/optimizeopt/test/test_optimizebasic.py @@ -3749,6 +3749,19 @@ """ self.optimize_loop(ops, expected) + def test_shift_zero(self): + ops = """ + [i0] + i1 = int_lshift(0, i0) + i2 = int_rshift(0, i0) + jump(i1, i2) + """ + expected = """ + [i0] + jump(0, 0) + """ + self.optimize_loop(ops, expected) + def test_bound_and(self): ops = """ [i0] From noreply at buildbot.pypy.org Sun Sep 29 01:40:15 2013 From: noreply at buildbot.pypy.org (alex_gaynor) Date: Sun, 29 Sep 2013 01:40:15 +0200 (CEST) Subject: [pypy-commit] extradoc extradoc: Another item Message-ID: <20130928234015.5B4871C073E@cobra.cs.uni-duesseldorf.de> Author: Alex Gaynor Branch: extradoc Changeset: r5063:3b49b3a9ae91 Date: 2013-09-28 16:40 -0700 http://bitbucket.org/pypy/extradoc/changeset/3b49b3a9ae91/ Log: Another item diff --git a/planning/jit.txt b/planning/jit.txt --- a/planning/jit.txt +++ b/planning/jit.txt @@ -48,6 +48,9 @@ - {}.update({}) is not fully unrolled and constant folded because HeapCache loses track of values in virtual-to-virtual ARRAY_COPY calls. +- ovfcheck(a << b) will do ``result >> b`` and check that the result is equal + to ``a``, instead of looking at the x86 flags. + OPTIMIZATIONS ------------- From noreply at buildbot.pypy.org Sun Sep 29 03:55:39 2013 From: noreply at buildbot.pypy.org (alex_gaynor) Date: Sun, 29 Sep 2013 03:55:39 +0200 (CEST) Subject: [pypy-commit] pypy default: MAke this code more readable Message-ID: <20130929015539.951C71C073E@cobra.cs.uni-duesseldorf.de> Author: Alex Gaynor Branch: Changeset: r67132:fc180280f824 Date: 2013-09-28 18:55 -0700 http://bitbucket.org/pypy/pypy/changeset/fc180280f824/ Log: MAke this code more readable 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 @@ -125,7 +125,7 @@ for descr, cache in self.heap_array_cache.iteritems(): for idx, cache in cache.iteritems(): for frombox in cache.keys(): - if not self.new_boxes.get(frombox, False): + if not self.is_unescaped(frombox): del cache[frombox] return else: diff --git a/rpython/jit/metainterp/optimizeopt/simplify.py b/rpython/jit/metainterp/optimizeopt/simplify.py --- a/rpython/jit/metainterp/optimizeopt/simplify.py +++ b/rpython/jit/metainterp/optimizeopt/simplify.py @@ -45,7 +45,7 @@ return self.optimize_JUMP(op.copy_and_change(rop.JUMP)) self.last_label_descr = op.getdescr() self.emit_operation(op) - + def optimize_JUMP(self, op): if not self.unroll: descr = op.getdescr() From noreply at buildbot.pypy.org Sun Sep 29 04:19:42 2013 From: noreply at buildbot.pypy.org (alex_gaynor) Date: Sun, 29 Sep 2013 04:19:42 +0200 (CEST) Subject: [pypy-commit] pypy default: Fish the descr in the tracing HeapCache when optimizing LL_ARRAYCOPY Message-ID: <20130929021942.EAC591C154F@cobra.cs.uni-duesseldorf.de> Author: Alex Gaynor Branch: Changeset: r67133:7bf619e411bf Date: 2013-09-28 19:19 -0700 http://bitbucket.org/pypy/pypy/changeset/7bf619e411bf/ Log: Fish the descr in the tracing HeapCache when optimizing LL_ARRAYCOPY 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 @@ -117,12 +117,15 @@ # effects are so well defined. elif effectinfo.oopspecindex == effectinfo.OS_ARRAYCOPY: # The destination box - if argboxes[2] in self.new_boxes: - # XXX: no descr here so we invalidate any of them, not just - # of the correct type - # XXX: in theory the indices of the copy could be looked at - # as well - for descr, cache in self.heap_array_cache.iteritems(): + if ( + argboxes[2] in self.new_boxes and + len(effectinfo.write_descrs_arrays) == 1 + ): + # Fish the descr out of the effectinfo + cache = self.heap_array_cache.get(effectinfo.write_descrs_arrays[0]) + if cache is not None: + # XXX: in theory the indices of the copy could be + # looked at for idx, cache in cache.iteritems(): for frombox in cache.keys(): if not self.is_unescaped(frombox): diff --git a/rpython/jit/metainterp/test/test_heapcache.py b/rpython/jit/metainterp/test/test_heapcache.py --- a/rpython/jit/metainterp/test/test_heapcache.py +++ b/rpython/jit/metainterp/test/test_heapcache.py @@ -29,17 +29,24 @@ OS_ARRAYCOPY = 0 - def __init__(self, extraeffect, oopspecindex): + def __init__(self, extraeffect, oopspecindex, write_descrs_arrays): self.extraeffect = extraeffect self.oopspecindex = oopspecindex + self.write_descrs_arrays = write_descrs_arrays + class FakeCallDescr(object): - def __init__(self, extraeffect, oopspecindex=None): + def __init__(self, extraeffect, oopspecindex=None, write_descrs_arrays=[]): self.extraeffect = extraeffect self.oopspecindex = oopspecindex + self.write_descrs_arrays = write_descrs_arrays def get_extra_info(self): - return FakeEffectinfo(self.extraeffect, self.oopspecindex) + return FakeEffectinfo( + self.extraeffect, self.oopspecindex, + write_descrs_arrays=self.write_descrs_arrays + ) + class TestHeapCache(object): def test_known_class_box(self): @@ -364,13 +371,13 @@ # Just need the destination box for this call h.invalidate_caches( rop.CALL, - FakeCallDescr(FakeEffectinfo.EF_CANNOT_RAISE, FakeEffectinfo.OS_ARRAYCOPY), + FakeCallDescr(FakeEffectinfo.EF_CANNOT_RAISE, FakeEffectinfo.OS_ARRAYCOPY, write_descrs_arrays=[descr1]), [None, None, box2, None, None] ) assert h.getarrayitem(box1, index1, descr1) is box2 h.invalidate_caches( rop.CALL, - FakeCallDescr(FakeEffectinfo.EF_CANNOT_RAISE, FakeEffectinfo.OS_ARRAYCOPY), + FakeCallDescr(FakeEffectinfo.EF_CANNOT_RAISE, FakeEffectinfo.OS_ARRAYCOPY, write_descrs_arrays=[descr1]), [None, None, box3, None, None] ) assert h.getarrayitem(box1, index1, descr1) is None @@ -379,11 +386,24 @@ assert h.getarrayitem(box4, index1, descr1) is box2 h.invalidate_caches( rop.CALL, - FakeCallDescr(FakeEffectinfo.EF_CANNOT_RAISE, FakeEffectinfo.OS_ARRAYCOPY), + FakeCallDescr(FakeEffectinfo.EF_CANNOT_RAISE, FakeEffectinfo.OS_ARRAYCOPY, write_descrs_arrays=[descr1]), [None, None, box2, None, None] ) assert h.getarrayitem(box4, index1, descr1) is None + def test_ll_arraycopy_differing_descrs(self): + h = HeapCache() + h.setarrayitem(box1, index1, box2, descr1) + assert h.getarrayitem(box1, index1, descr1) is box2 + h.new_array(box2, lengthbox2) + h.invalidate_caches( + rop.CALL, + FakeCallDescr(FakeEffectinfo.EF_CANNOT_RAISE, FakeEffectinfo.OS_ARRAYCOPY, write_descrs_arrays=[descr2]), + [None, None, box2, None, None] + ) + assert h.getarrayitem(box1, index1, descr1) is box2 + + def test_unescaped(self): h = HeapCache() assert not h.is_unescaped(box1) From noreply at buildbot.pypy.org Sun Sep 29 18:10:02 2013 From: noreply at buildbot.pypy.org (alex_gaynor) Date: Sun, 29 Sep 2013 18:10:02 +0200 (CEST) Subject: [pypy-commit] pypy default: fix translation Message-ID: <20130929161002.E524C1C0177@cobra.cs.uni-duesseldorf.de> Author: Alex Gaynor Branch: Changeset: r67134:b276b99a50c9 Date: 2013-09-29 09:09 -0700 http://bitbucket.org/pypy/pypy/changeset/b276b99a50c9/ Log: fix translation 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 @@ -122,7 +122,7 @@ len(effectinfo.write_descrs_arrays) == 1 ): # Fish the descr out of the effectinfo - cache = self.heap_array_cache.get(effectinfo.write_descrs_arrays[0]) + cache = self.heap_array_cache.get(effectinfo.write_descrs_arrays[0], None) if cache is not None: # XXX: in theory the indices of the copy could be # looked at From noreply at buildbot.pypy.org Sun Sep 29 18:58:05 2013 From: noreply at buildbot.pypy.org (alex_gaynor) Date: Sun, 29 Sep 2013 18:58:05 +0200 (CEST) Subject: [pypy-commit] pypy default: Perform fewer dict lookups here Message-ID: <20130929165806.00DF81C029E@cobra.cs.uni-duesseldorf.de> Author: Alex Gaynor Branch: Changeset: r67135:7066133c5cfc Date: 2013-09-29 09:57 -0700 http://bitbucket.org/pypy/pypy/changeset/7066133c5cfc/ Log: Perform fewer dict lookups here 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 @@ -87,9 +87,11 @@ def _escape(self, box): if box in self.new_boxes: self.new_boxes[box] = False - if box in self.dependencies: - deps = self.dependencies[box] - del self.dependencies[box] + try: + deps = self.dependencies.pop(box) + except KeyError: + pass + else: for dep in deps: self._escape(dep) From noreply at buildbot.pypy.org Sun Sep 29 19:52:48 2013 From: noreply at buildbot.pypy.org (alex_gaynor) Date: Sun, 29 Sep 2013 19:52:48 +0200 (CEST) Subject: [pypy-commit] pypy default: Refs issue1606 -- unskipped this test by making it more flexible Message-ID: <20130929175248.28DE21C0219@cobra.cs.uni-duesseldorf.de> Author: Alex Gaynor Branch: Changeset: r67136:c2079f32123d Date: 2013-09-29 10:52 -0700 http://bitbucket.org/pypy/pypy/changeset/c2079f32123d/ Log: Refs issue1606 -- unskipped this test by making it more flexible 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 @@ -1,4 +1,3 @@ -import py from pypy.module.pypyjit.test_pypy_c.test_00_model import BaseTestPyPyC @@ -51,7 +50,6 @@ """) def test_lock_acquire_release(self): - py.test.skip("test too precise, please fix me") def main(n): import threading lock = threading.Lock() @@ -63,34 +61,34 @@ loop, = log.loops_by_filename(self.filepath) assert loop.match(""" i58 = int_gt(i43, 0) - guard_true(i58, descr=) - p59 = getfield_gc(p15, descr=) - i60 = getfield_gc(p59, descr=) + guard_true(i58, descr=...) + p59 = getfield_gc(p15, descr=) + i60 = getfield_gc(p59, descr=) p61 = force_token() - setfield_gc(p0, p61, descr=) - i62 = call_release_gil(4312440032, i60, 1, descr=) - guard_not_forced(descr=) - guard_no_exception(descr=) + setfield_gc(p0, p61, descr=) + i62 = call_release_gil(..., i60, 1, descr=) + guard_not_forced(descr=...) + guard_no_exception(descr=...) i63 = int_is_true(i62) - guard_true(i63, descr=) + guard_true(i63, descr=...) i64 = int_sub(i43, 1) - guard_not_invalidated(descr=) - p66 = getfield_gc(p15, descr=) - i67 = getfield_gc(p66, descr=) + guard_not_invalidated(descr=...) + p66 = getfield_gc(p15, descr=) + i67 = getfield_gc(p66, descr=) p68 = force_token() - setfield_gc(p0, p68, descr=) - i69 = call_release_gil(4312440032, i67, 0, descr=) - guard_not_forced(descr=) - guard_no_exception(descr=) + setfield_gc(p0, p68, descr=) + i69 = call_release_gil(..., i67, 0, descr=) + guard_not_forced(descr=...) + guard_no_exception(descr=...) i70 = int_is_true(i69) - guard_false(i70, descr=) - i71 = getfield_gc(p66, descr=) + guard_false(i70, descr=...) + i71 = getfield_gc(p66, descr=) p72 = force_token() - setfield_gc(p0, p72, descr=) - call_release_gil(4312441056, i71, descr=) - guard_not_forced(descr=) - guard_no_exception(descr=) - guard_not_invalidated(descr=) + setfield_gc(p0, p72, descr=) + call_release_gil(..., i71, descr=) + guard_not_forced(descr=...) + guard_no_exception(descr=...) + guard_not_invalidated(descr=...) --TICK-- - jump(..., descr=TargetToken(4361239720)) + jump(..., descr=...) """) From noreply at buildbot.pypy.org Sun Sep 29 21:24:57 2013 From: noreply at buildbot.pypy.org (alex_gaynor) Date: Sun, 29 Sep 2013 21:24:57 +0200 (CEST) Subject: [pypy-commit] pypy default: Mark two fields in locks as immutable Message-ID: <20130929192457.D6EA31C0177@cobra.cs.uni-duesseldorf.de> Author: Alex Gaynor Branch: Changeset: r67137:ff6ca9a4d01c Date: 2013-09-29 12:24 -0700 http://bitbucket.org/pypy/pypy/changeset/ff6ca9a4d01c/ Log: Mark two fields in locks as immutable 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 @@ -60,32 +60,27 @@ assert log.result == main(500) loop, = log.loops_by_filename(self.filepath) assert loop.match(""" - i58 = int_gt(i43, 0) + i55 = int_gt(i43, 0) + guard_true(i55, descr=...) + p56 = force_token() + setfield_gc(p0, p56, descr=) + i57 = call_release_gil(..., i36, 1, descr=) + guard_not_forced(descr=...) + guard_no_exception(descr=...) + i58 = int_is_true(i57) guard_true(i58, descr=...) - p59 = getfield_gc(p15, descr=) - i60 = getfield_gc(p59, descr=) + i59 = int_sub(i43, 1) + guard_not_invalidated(descr=...) p61 = force_token() setfield_gc(p0, p61, descr=) - i62 = call_release_gil(..., i60, 1, descr=) + i62 = call_release_gil(..., i36, 0, descr=) guard_not_forced(descr=...) guard_no_exception(descr=...) i63 = int_is_true(i62) - guard_true(i63, descr=...) - i64 = int_sub(i43, 1) - guard_not_invalidated(descr=...) - p66 = getfield_gc(p15, descr=) - i67 = getfield_gc(p66, descr=) - p68 = force_token() - setfield_gc(p0, p68, descr=) - i69 = call_release_gil(..., i67, 0, descr=) - guard_not_forced(descr=...) - guard_no_exception(descr=...) - i70 = int_is_true(i69) - guard_false(i70, descr=...) - i71 = getfield_gc(p66, descr=) - p72 = force_token() - setfield_gc(p0, p72, descr=) - call_release_gil(..., i71, descr=) + guard_false(i63, descr=...) + p64 = force_token() + setfield_gc(p0, p64, descr=) + call_release_gil(4312494624, i36, descr=) guard_not_forced(descr=...) guard_no_exception(descr=...) guard_not_invalidated(descr=...) 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 @@ -26,6 +26,8 @@ class Lock(W_Root): "A box around an interp-level lock object." + _immutable_fields_ = ["lock"] + def __init__(self, space): self.space = space try: diff --git a/rpython/rlib/rthread.py b/rpython/rlib/rthread.py --- a/rpython/rlib/rthread.py +++ b/rpython/rlib/rthread.py @@ -117,6 +117,8 @@ """ Container for low-level implementation of a lock object """ + _immutable_fields_ = ["_lock"] + def __init__(self, ll_lock): self._lock = ll_lock From noreply at buildbot.pypy.org Mon Sep 30 06:05:21 2013 From: noreply at buildbot.pypy.org (alex_gaynor) Date: Mon, 30 Sep 2013 06:05:21 +0200 (CEST) Subject: [pypy-commit] pypy default: Don't hardcode this address Message-ID: <20130930040521.338B41C364C@cobra.cs.uni-duesseldorf.de> Author: Alex Gaynor Branch: Changeset: r67138:ccabdc2acd00 Date: 2013-09-29 21:04 -0700 http://bitbucket.org/pypy/pypy/changeset/ccabdc2acd00/ Log: Don't hardcode this address 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 @@ -80,7 +80,7 @@ guard_false(i63, descr=...) p64 = force_token() setfield_gc(p0, p64, descr=) - call_release_gil(4312494624, i36, descr=) + call_release_gil(..., i36, descr=) guard_not_forced(descr=...) guard_no_exception(descr=...) guard_not_invalidated(descr=...) From noreply at buildbot.pypy.org Mon Sep 30 06:06:34 2013 From: noreply at buildbot.pypy.org (alex_gaynor) Date: Mon, 30 Sep 2013 06:06:34 +0200 (CEST) Subject: [pypy-commit] pypy default: Updated this test for the new optimization Message-ID: <20130930040634.5B68A1C364C@cobra.cs.uni-duesseldorf.de> Author: Alex Gaynor Branch: Changeset: r67139:f280bdb646f1 Date: 2013-09-29 21:06 -0700 http://bitbucket.org/pypy/pypy/changeset/f280bdb646f1/ Log: Updated this test for the new optimization 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 @@ -113,7 +113,7 @@ i13 = strgetitem(p9, 0) i15 = int_eq(i13, 45) guard_false(i15, descr=...) - i17 = int_sub(0, i10) + i17 = int_neg(i10) i19 = int_gt(i10, 23) guard_false(i19, descr=...) p21 = newstr(23) From noreply at buildbot.pypy.org Mon Sep 30 06:46:53 2013 From: noreply at buildbot.pypy.org (alex_gaynor) Date: Mon, 30 Sep 2013 06:46:53 +0200 (CEST) Subject: [pypy-commit] pypy default: Fixed issue1617 -- when a local is deleted, ensure it doesn't show up in locals() Message-ID: <20130930044653.30CD51C33B0@cobra.cs.uni-duesseldorf.de> Author: Alex Gaynor Branch: Changeset: r67140:8940f38137e1 Date: 2013-09-29 21:45 -0700 http://bitbucket.org/pypy/pypy/changeset/8940f38137e1/ Log: Fixed issue1617 -- when a local is deleted, ensure it doesn't show up in locals() diff --git a/pypy/interpreter/eval.py b/pypy/interpreter/eval.py --- a/pypy/interpreter/eval.py +++ b/pypy/interpreter/eval.py @@ -107,9 +107,15 @@ for i in range(min(len(varnames), self.getfastscopelength())): name = varnames[i] w_value = fastscope_w[i] + w_name = self.space.wrap(name) if w_value is not None: - w_name = self.space.wrap(name) self.space.setitem(self.w_locals, w_name, w_value) + else: + try: + self.space.delitem(self.w_locals, w_name) + except OperationError as e: + if not e.maches(self.space.w_KeyError): + raise def locals2fast(self): # Copy values from self.w_locals to the fastlocals 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 @@ -83,10 +83,21 @@ def test_locals(self): def f(): return locals() + def g(c=0, b=0, a=0): return locals() + assert f() == {} - assert g() == {'a':0, 'b':0, 'c':0} + assert g() == {'a': 0, 'b': 0, 'c': 0} + + def test_locals_deleted_local(self): + def f(): + a = 3 + locals() + del a + return locals() + + assert f() == {} def test_dir(self): def f(): diff --git a/rpython/flowspace/test/test_objspace.py b/rpython/flowspace/test/test_objspace.py --- a/rpython/flowspace/test/test_objspace.py +++ b/rpython/flowspace/test/test_objspace.py @@ -1063,7 +1063,6 @@ assert len(graph.startblock.exits) == 1 assert graph.startblock.exits[0].target == graph.returnblock - def test_global_variable(self): def global_var_missing(): return a From noreply at buildbot.pypy.org Mon Sep 30 06:50:23 2013 From: noreply at buildbot.pypy.org (alex_gaynor) Date: Mon, 30 Sep 2013 06:50:23 +0200 (CEST) Subject: [pypy-commit] pypy default: Probably we don't care about things that have been removed for nearly a decade Message-ID: <20130930045023.3E3101C13E7@cobra.cs.uni-duesseldorf.de> Author: Alex Gaynor Branch: Changeset: r67141:70a0fb93833b Date: 2013-09-29 21:49 -0700 http://bitbucket.org/pypy/pypy/changeset/70a0fb93833b/ Log: Probably we don't care about things that have been removed for nearly a decade 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 @@ -263,25 +263,9 @@ assert next(x) == 3 def test_xrange_args(self): -## # xrange() attributes are deprecated and were removed in Python 2.3. -## x = xrange(2) -## assert x.start == 0 -## assert x.stop == 2 -## assert x.step == 1 - -## x = xrange(2,10,2) -## assert x.start == 2 -## assert x.stop == 10 -## assert x.step == 2 - -## x = xrange(2.3, 10.5, 2.4) -## assert x.start == 2 -## assert x.stop == 10 -## assert x.step == 2 - raises(ValueError, xrange, 0, 1, 0) - def test_xrange_repr(self): + def test_xrange_repr(self): assert repr(xrange(1)) == 'xrange(1)' assert repr(xrange(1,2)) == 'xrange(1, 2)' assert repr(xrange(1,2,3)) == 'xrange(1, 4, 3)' @@ -340,7 +324,7 @@ raises(TypeError, xrange, 1, 3+2j) raises(TypeError, xrange, 1, 2, '1') raises(TypeError, xrange, 1, 2, 3+2j) - + def test_sorted(self): l = [] sorted_l = sorted(l) @@ -359,7 +343,7 @@ 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) rev = reversed(l) @@ -375,8 +359,8 @@ return 42 obj = SomeClass() assert reversed(obj) == 42 - - + + def test_cmp(self): assert cmp(9,9) == 0 assert cmp(0,9) < 0 @@ -409,7 +393,7 @@ raises(RuntimeError, cmp, a, c) # okay, now break the cycles a.pop(); b.pop(); c.pop() - + def test_coerce(self): assert coerce(1, 2) == (1, 2) assert coerce(1L, 2L) == (1L, 2L) @@ -476,7 +460,7 @@ assert eval("1+2") == 3 assert eval(" \t1+2\n") == 3 assert eval("len([])") == 0 - assert eval("len([])", {}) == 0 + assert eval("len([])", {}) == 0 # cpython 2.4 allows this (raises in 2.3) assert eval("3", None, None) == 3 i = 4 @@ -694,15 +678,15 @@ w_value = space.getitem(w_dict, space.wrap('i')) assert space.eq_w(w_value, space.wrap(42)) - def test_execfile_different_lineendings(self, space): + def test_execfile_different_lineendings(self, space): from rpython.tool.udir import udir d = udir.ensure('lineending', dir=1) - dos = d.join('dos.py') - f = dos.open('wb') + dos = d.join('dos.py') + f = dos.open('wb') f.write("x=3\r\n\r\ny=4\r\n") - f.close() + f.close() space.appexec([space.wrap(str(dos))], """ - (filename): + (filename): d = {} execfile(filename, d) assert d['x'] == 3 @@ -710,12 +694,12 @@ """) unix = d.join('unix.py') - f = unix.open('wb') + f = unix.open('wb') f.write("x=5\n\ny=6\n") - f.close() + f.close() space.appexec([space.wrap(str(unix))], """ - (filename): + (filename): d = {} execfile(filename, d) assert d['x'] == 5 From noreply at buildbot.pypy.org Mon Sep 30 06:52:41 2013 From: noreply at buildbot.pypy.org (alex_gaynor) Date: Mon, 30 Sep 2013 06:52:41 +0200 (CEST) Subject: [pypy-commit] pypy default: Fix an emberassing typo Message-ID: <20130930045241.3B3EC1C13E7@cobra.cs.uni-duesseldorf.de> Author: Alex Gaynor Branch: Changeset: r67142:b49818a92164 Date: 2013-09-29 21:51 -0700 http://bitbucket.org/pypy/pypy/changeset/b49818a92164/ Log: Fix an emberassing typo diff --git a/pypy/interpreter/eval.py b/pypy/interpreter/eval.py --- a/pypy/interpreter/eval.py +++ b/pypy/interpreter/eval.py @@ -114,7 +114,7 @@ try: self.space.delitem(self.w_locals, w_name) except OperationError as e: - if not e.maches(self.space.w_KeyError): + if not e.match(self.space, self.space.w_KeyError): raise def locals2fast(self): From noreply at buildbot.pypy.org Mon Sep 30 08:25:49 2013 From: noreply at buildbot.pypy.org (alex_gaynor) Date: Mon, 30 Sep 2013 08:25:49 +0200 (CEST) Subject: [pypy-commit] pypy default: Use the slightly simpler isfinite, makes math.fsum perhaps a nanosecond faster Message-ID: <20130930062549.8AC9B1C0219@cobra.cs.uni-duesseldorf.de> Author: Alex Gaynor Branch: Changeset: r67143:b441e4fd93e5 Date: 2013-09-29 23:25 -0700 http://bitbucket.org/pypy/pypy/changeset/b441e4fd93e5/ Log: Use the slightly simpler isfinite, makes math.fsum perhaps a nanosecond faster 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 @@ -334,7 +334,7 @@ v = hi del partials[added:] if v != 0.0: - if rfloat.isinf(v) or rfloat.isnan(v): + if not rfloat.isfinite(v): if (not rfloat.isinf(original) and not rfloat.isnan(original)): raise OperationError(space.w_OverflowError, From noreply at buildbot.pypy.org Mon Sep 30 16:46:56 2013 From: noreply at buildbot.pypy.org (alex_gaynor) Date: Mon, 30 Sep 2013 16:46:56 +0200 (CEST) Subject: [pypy-commit] pypy default: Use the simpler isfinite in another place Message-ID: <20130930144656.5C6DF1C029E@cobra.cs.uni-duesseldorf.de> Author: Alex Gaynor Branch: Changeset: r67144:87d6e936413b Date: 2013-09-30 07:46 -0700 http://bitbucket.org/pypy/pypy/changeset/87d6e936413b/ Log: Use the simpler isfinite in another place 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 @@ -335,8 +335,7 @@ del partials[added:] if v != 0.0: if not rfloat.isfinite(v): - if (not rfloat.isinf(original) and - not rfloat.isnan(original)): + if rfloat.isfinite(original): raise OperationError(space.w_OverflowError, space.wrap("intermediate overflow")) if rfloat.isinf(original):